summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2008-10-04 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2008-10-04 08:01:00 -0700
commiteb75697fe00a8668f74b3c710dcbf5658e07d167 (patch)
tree05b78ce8fb95fcc37b013f5bfd9da0dd3544b42a
parent689cbe904e3a28d7502feb9931b748764f947aaf (diff)
downloadabc-eb75697fe00a8668f74b3c710dcbf5658e07d167.tar.gz
abc-eb75697fe00a8668f74b3c710dcbf5658e07d167.tar.bz2
abc-eb75697fe00a8668f74b3c710dcbf5658e07d167.zip
Version abc81004
-rw-r--r--abc.dsp16
-rw-r--r--src/aig/aig/aig.h15
-rw-r--r--src/aig/cec/cecSat.c284
-rw-r--r--src/aig/saig/saig.h6
-rw-r--r--src/aig/saig/saigMiter.c599
-rw-r--r--src/aig/saig/saigSynch.c34
-rw-r--r--src/aig/ssw/ssw.h3
-rw-r--r--src/aig/ssw/sswPart.c14
-rw-r--r--src/aig/ssw_old/module.make14
-rw-r--r--src/aig/ssw_old/ssw.h117
-rw-r--r--src/aig/ssw_old/sswAig.c205
-rw-r--r--src/aig/ssw_old/sswBmc.c315
-rw-r--r--src/aig/ssw_old/sswClass.c941
-rw-r--r--src/aig/ssw_old/sswCnf.c335
-rw-r--r--src/aig/ssw_old/sswCore.c293
-rw-r--r--src/aig/ssw_old/sswInt.h232
-rw-r--r--src/aig/ssw_old/sswLcorr.c364
-rw-r--r--src/aig/ssw_old/sswMan.c237
-rw-r--r--src/aig/ssw_old/sswPairs.c470
-rw-r--r--src/aig/ssw_old/sswPart.c129
-rw-r--r--src/aig/ssw_old/sswSat.c264
-rw-r--r--src/aig/ssw_old/sswSim.c1334
-rw-r--r--src/aig/ssw_old/sswSimSat.c199
-rw-r--r--src/aig/ssw_old/sswSweep.c473
-rw-r--r--src/aig/ssw_old/sswUnique.c290
-rw-r--r--src/base/abci/abc.c116
-rw-r--r--src/base/abci/abc.zipbin0 -> 62408 bytes
-rw-r--r--src/base/abci/abcDar.c145
-rw-r--r--src/base/cmd/cmd.c20
-rw-r--r--src/base/cmd/cmd.h13
-rw-r--r--src/base/io/io.c48
-rw-r--r--src/base/main/mainUtils.c18
-rw-r--r--src/misc/extra/extra.h36
-rw-r--r--src/sat/bsat/satChecker.c187
-rw-r--r--src/sat/bsat/satInterA.c26
-rw-r--r--src/sat/bsat/satInterA_mod.c1104
-rw-r--r--src/sat/bsat/satInterA_old.c1047
-rw-r--r--src/sat/bsat/satInterA_yu_hu.c87
-rw-r--r--src/sat/lsat/solver.h124
39 files changed, 10024 insertions, 130 deletions
diff --git a/abc.dsp b/abc.dsp
index 8f3cfbe2..9ef7952a 100644
--- a/abc.dsp
+++ b/abc.dsp
@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/misc/bzlib" /I "src/misc/zlib" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/sat/nsat" /I "src/sat/psat" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /I "src/aig/mfx" /I "src/aig/saig" /I "src/aig/bbr" /I "src/aig/int" /I "src/aig/dch" /I "src/aig/ssw" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D ABC_DLL=DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_LIBRARIES" /FR /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/misc/bzlib" /I "src/misc/zlib" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/sat/nsat" /I "src/sat/psat" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /I "src/aig/mfx" /I "src/aig/saig" /I "src/aig/bbr" /I "src/aig/int" /I "src/aig/dch" /I "src/aig/ssw" /I "src/sat/lsat" /I "src/aig/cec" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D ABC_DLL=DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_LIBRARIES" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/misc/bzlib" /I "src/misc/zlib" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/sat/nsat" /I "src/sat/psat" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /I "src/aig/mfx" /I "src/aig/saig" /I "src/aig/bbr" /I "src/aig/int" /I "src/aig/dch" /I "src/aig/ssw" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D ABC_DLL=DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_LIBRARIES" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/misc/bzlib" /I "src/misc/zlib" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/sat/nsat" /I "src/sat/psat" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /I "src/aig/mfx" /I "src/aig/saig" /I "src/aig/bbr" /I "src/aig/int" /I "src/aig/dch" /I "src/aig/ssw" /I "src/sat/lsat" /I "src/aig/cec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D ABC_DLL=DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_LIBRARIES" /FR /YX /FD /GZ /c
# SUBTRACT CPP /X
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
@@ -1261,6 +1261,14 @@ SOURCE=.\src\sat\psat\m114p_types.h
# PROP Default_Filter ""
# End Group
+# Begin Group "lsat"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\src\sat\lsat\solver.h
+# End Source File
+# End Group
# End Group
# Begin Group "opt"
@@ -3501,6 +3509,10 @@ SOURCE=.\src\aig\ssw\sswSweep.c
SOURCE=.\src\aig\ssw\sswUnique.c
# End Source File
# End Group
+# Begin Group "cec"
+
+# PROP Default_Filter ""
+# End Group
# End Group
# End Group
# Begin Group "Header Files"
diff --git a/src/aig/aig/aig.h b/src/aig/aig/aig.h
index 503985b7..7480df78 100644
--- a/src/aig/aig/aig.h
+++ b/src/aig/aig/aig.h
@@ -194,6 +194,17 @@ struct Aig_ManCut_t_
unsigned * puTemp[4]; // used for the truth table computation
};
+#ifdef WIN32
+#define DLLEXPORT __declspec(dllexport)
+#define DLLIMPORT __declspec(dllimport)
+#else /* defined(WIN32) */
+#define DLLIMPORT
+#endif /* defined(WIN32) */
+
+#ifndef ABC_DLL
+#define ABC_DLL DLLIMPORT
+#endif
+
static inline Aig_Cut_t * Aig_ObjCuts( Aig_ManCut_t * p, Aig_Obj_t * pObj ) { return p->pCuts[pObj->Id]; }
static inline void Aig_ObjSetCuts( Aig_ManCut_t * p, Aig_Obj_t * pObj, Aig_Cut_t * pCuts ) { p->pCuts[pObj->Id] = pCuts; }
@@ -452,7 +463,7 @@ static inline int Aig_ObjFanoutNext( Aig_Man_t * p, int iFan ) { assert(iF
////////////////////////////////////////////////////////////////////////
/*=== aigCheck.c ========================================================*/
-extern int Aig_ManCheck( Aig_Man_t * p );
+extern ABC_DLL int Aig_ManCheck( Aig_Man_t * p );
extern void Aig_ManCheckMarkA( Aig_Man_t * p );
extern void Aig_ManCheckPhase( Aig_Man_t * p );
/*=== aigCuts.c ========================================================*/
@@ -502,7 +513,7 @@ extern Aig_Man_t * Aig_ManFrames( Aig_Man_t * pAig, int nFs, int fInit, int
extern Aig_Man_t * Aig_ManStart( int nNodesMax );
extern Aig_Man_t * Aig_ManStartFrom( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManExtractMiter( Aig_Man_t * p, Aig_Obj_t * pNode1, Aig_Obj_t * pNode2 );
-extern void Aig_ManStop( Aig_Man_t * p );
+extern ABC_DLL void Aig_ManStop( Aig_Man_t * p );
extern int Aig_ManCleanup( Aig_Man_t * p );
extern int Aig_ManAntiCleanup( Aig_Man_t * p );
extern int Aig_ManPiCleanup( Aig_Man_t * p );
diff --git a/src/aig/cec/cecSat.c b/src/aig/cec/cecSat.c
new file mode 100644
index 00000000..37f63f05
--- /dev/null
+++ b/src/aig/cec/cecSat.c
@@ -0,0 +1,284 @@
+/**CFile****************************************************************
+
+ FileName [cecSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Backend calling the SAT solver.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 30, 2007.]
+
+ Revision [$Id: cecSat.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig.h"
+#include "cnf.h"
+#include "solver.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Writes CNF into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+solver * Cnf_WriteIntoSolverNew( Cnf_Dat_t * p )
+{
+ solver * pSat;
+ int i, status;
+ pSat = solver_new();
+ for ( i = 0; i < p->nVars; i++ )
+ solver_newVar( pSat );
+ for ( i = 0; i < p->nClauses; i++ )
+ {
+ if ( !solver_addClause( pSat, p->pClauses[i+1]-p->pClauses[i], p->pClauses[i] ) )
+ {
+ solver_delete( pSat );
+ return NULL;
+ }
+ }
+ status = solver_simplify(pSat);
+ if ( status == 0 )
+ {
+ solver_delete( pSat );
+ return NULL;
+ }
+ return pSat;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds the OR-clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cnf_DataWriteAndClausesNew( void * p, Cnf_Dat_t * pCnf )
+{
+/*
+ sat_solver * pSat = p;
+ Aig_Obj_t * pObj;
+ int i, Lit;
+ Aig_ManForEachPo( pCnf->pMan, pObj, i )
+ {
+ Lit = toLitCond( pCnf->pVarNums[pObj->Id], 0 );
+ if ( !sat_solver_addclause( pSat, &Lit, &Lit+1 ) )
+ return 0;
+ }
+*/
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds the OR-clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cnf_DataWriteOrClauseNew( solver * pSat, Cnf_Dat_t * pCnf )
+{
+ Aig_Obj_t * pObj;
+ int i, * pLits;
+ pLits = ALLOC( int, Aig_ManPoNum(pCnf->pMan) );
+ Aig_ManForEachPo( pCnf->pMan, pObj, i )
+ pLits[i] = solver_mkLit_args( pCnf->pVarNums[pObj->Id], 0 );
+ if ( !solver_addClause( pSat, Aig_ManPoNum(pCnf->pMan), pLits ) )
+ {
+ free( pLits );
+ return 0;
+ }
+ free( pLits );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Writes the given clause in a file in DIMACS format.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sat_SolverPrintStatsNew( FILE * pFile, solver * pSat )
+{
+// printf( "starts : %8d\n", solver_num_assigns(pSat) );
+ printf( "vars : %8d\n", solver_num_vars(pSat) );
+ printf( "clauses : %8d\n", solver_num_clauses(pSat) );
+ printf( "conflicts : %8d\n", solver_num_learnts(pSat) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns a counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Sat_SolverGetModelNew( solver * pSat, int * pVars, int nVars )
+{
+ int * pModel;
+ int i;
+ pModel = ALLOC( int, nVars+1 );
+ for ( i = 0; i < nVars; i++ )
+ {
+ assert( pVars[i] >= 0 && pVars[i] < solver_num_vars(pSat) );
+ pModel[i] = (int)(solver_modelValue_Var( pSat, pVars[i] ) == solver_l_True);
+ }
+ return pModel;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_RunSat( Aig_Man_t * pMan, sint64 nConfLimit, sint64 nInsLimit, int fFlipBits, int fAndOuts, int fVerbose )
+{
+ solver * pSat;
+ Cnf_Dat_t * pCnf;
+ int status, RetValue, clk = clock();
+ Vec_Int_t * vCiIds;
+
+ assert( Aig_ManRegNum(pMan) == 0 );
+ pMan->pData = NULL;
+
+ // derive CNF
+ pCnf = Cnf_Derive( pMan, Aig_ManPoNum(pMan) );
+// pCnf = Cnf_DeriveSimple( pMan, Aig_ManPoNum(pMan) );
+
+ // convert into SAT solver
+ pSat = Cnf_WriteIntoSolverNew( pCnf );
+ if ( pSat == NULL )
+ {
+ Cnf_DataFree( pCnf );
+ return 1;
+ }
+
+
+ if ( fAndOuts )
+ {
+ assert( 0 );
+ // assert each output independently
+ if ( !Cnf_DataWriteAndClausesNew( pSat, pCnf ) )
+ {
+ solver_delete( pSat );
+ Cnf_DataFree( pCnf );
+ return 1;
+ }
+ }
+ else
+ {
+ // add the OR clause for the outputs
+ if ( !Cnf_DataWriteOrClauseNew( pSat, pCnf ) )
+ {
+ solver_delete( pSat );
+ Cnf_DataFree( pCnf );
+ return 1;
+ }
+ }
+ vCiIds = Cnf_DataCollectPiSatNums( pCnf, pMan );
+ Cnf_DataFree( pCnf );
+
+
+// printf( "Created SAT problem with %d variable and %d clauses. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) );
+// PRT( "Time", clock() - clk );
+
+ // simplify the problem
+ clk = clock();
+ status = solver_simplify(pSat);
+// printf( "Simplified the problem to %d variables and %d clauses. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) );
+// PRT( "Time", clock() - clk );
+ if ( status == 0 )
+ {
+ Vec_IntFree( vCiIds );
+ solver_delete( pSat );
+// printf( "The problem is UNSATISFIABLE after simplification.\n" );
+ return 1;
+ }
+
+ // solve the miter
+ clk = clock();
+ if ( fVerbose )
+ solver_set_verbosity( pSat, 1 );
+ status = solver_solve( pSat, 0, NULL );
+ if ( status == solver_l_Undef )
+ {
+// printf( "The problem timed out.\n" );
+ RetValue = -1;
+ }
+ else if ( status == solver_l_True )
+ {
+// printf( "The problem is SATISFIABLE.\n" );
+ RetValue = 0;
+ }
+ else if ( status == solver_l_False )
+ {
+// printf( "The problem is UNSATISFIABLE.\n" );
+ RetValue = 1;
+ }
+ else
+ assert( 0 );
+// PRT( "SAT sat_solver time", clock() - clk );
+// printf( "The number of conflicts = %d.\n", (int)pSat->sat_solver_stats.conflicts );
+
+ // if the problem is SAT, get the counterexample
+ if ( status == solver_l_True )
+ {
+ pMan->pData = Sat_SolverGetModelNew( pSat, vCiIds->pArray, vCiIds->nSize );
+ }
+ // free the sat_solver
+ if ( fVerbose )
+ Sat_SolverPrintStatsNew( stdout, pSat );
+//sat_solver_store_write( pSat, "trace.cnf" );
+//sat_solver_store_free( pSat );
+ solver_delete( pSat );
+ Vec_IntFree( vCiIds );
+ return RetValue;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/aig/saig/saig.h b/src/aig/saig/saig.h
index c7a40f96..ddae07e0 100644
--- a/src/aig/saig/saig.h
+++ b/src/aig/saig/saig.h
@@ -94,7 +94,9 @@ extern Aig_Man_t * Saig_ManReadBlif( char * pFileName );
extern int Saig_Interpolate( Aig_Man_t * pAig, Inter_ManParams_t * pPars, int * pDepth );
/*=== saigMiter.c ==========================================================*/
extern Aig_Man_t * Saig_ManCreateMiter( Aig_Man_t * p1, Aig_Man_t * p2, int Oper );
-extern Aig_Man_t * Saig_ManDupInitZero( Aig_Man_t * p );
+extern Aig_Man_t * Saig_ManCreateMiterComb( Aig_Man_t * p1, Aig_Man_t * p2, int Oper );
+extern Aig_Man_t * Saig_ManCreateMiterTwo( Aig_Man_t * pOld, Aig_Man_t * pNew, int nFrames );
+extern int Saig_ManDemiterSimple( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 );
/*=== saigPhase.c ==========================================================*/
extern Aig_Man_t * Saig_ManPhaseAbstract( Aig_Man_t * p, Vec_Int_t * vInits, int nFrames, int fIgnore, int fPrint, int fVerbose );
/*=== saigRetFwd.c ==========================================================*/
@@ -107,6 +109,8 @@ extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, in
extern int Saig_ManRetimeSteps( Aig_Man_t * p, int nSteps, int fForward, int fAddBugs );
/*=== saigScl.c ==========================================================*/
extern void Saig_ManReportUselessRegisters( Aig_Man_t * pAig );
+/*=== saigSynch.c ==========================================================*/
+extern Aig_Man_t * Saig_ManDupInitZero( Aig_Man_t * p );
/*=== saigTrans.c ==========================================================*/
extern Aig_Man_t * Saig_ManTimeframeSimplify( Aig_Man_t * pAig, int nFrames, int nFramesMax, int fInit, int fVerbose );
diff --git a/src/aig/saig/saigMiter.c b/src/aig/saig/saigMiter.c
index 5b18db6e..5efcd24d 100644
--- a/src/aig/saig/saigMiter.c
+++ b/src/aig/saig/saigMiter.c
@@ -30,7 +30,7 @@
/**Function*************************************************************
- Synopsis []
+ Synopsis [Creates sequential miter.]
Description []
@@ -39,59 +39,59 @@
SeeAlso []
***********************************************************************/
-Aig_Man_t * Saig_ManCreateMiter( Aig_Man_t * p1, Aig_Man_t * p2, int Oper )
+Aig_Man_t * Saig_ManCreateMiter( Aig_Man_t * p0, Aig_Man_t * p1, int Oper )
{
Aig_Man_t * pNew;
Aig_Obj_t * pObj;
int i;
- assert( Saig_ManRegNum(p1) > 0 || Saig_ManRegNum(p2) > 0 );
- assert( Saig_ManPiNum(p1) == Saig_ManPiNum(p2) );
- assert( Saig_ManPoNum(p1) == Saig_ManPoNum(p2) );
- pNew = Aig_ManStart( Aig_ManObjNumMax(p1) + Aig_ManObjNumMax(p2) );
+ assert( Saig_ManRegNum(p0) > 0 || Saig_ManRegNum(p1) > 0 );
+ assert( Saig_ManPiNum(p0) == Saig_ManPiNum(p1) );
+ assert( Saig_ManPoNum(p0) == Saig_ManPoNum(p1) );
+ pNew = Aig_ManStart( Aig_ManObjNumMax(p0) + Aig_ManObjNumMax(p1) );
pNew->pName = Aig_UtilStrsav( "miter" );
// map constant nodes
+ Aig_ManConst1(p0)->pData = Aig_ManConst1(pNew);
Aig_ManConst1(p1)->pData = Aig_ManConst1(pNew);
- Aig_ManConst1(p2)->pData = Aig_ManConst1(pNew);
// map primary inputs
- Saig_ManForEachPi( p1, pObj, i )
+ Saig_ManForEachPi( p0, pObj, i )
pObj->pData = Aig_ObjCreatePi( pNew );
- Saig_ManForEachPi( p2, pObj, i )
+ Saig_ManForEachPi( p1, pObj, i )
pObj->pData = Aig_ManPi( pNew, i );
// map register outputs
- Saig_ManForEachLo( p1, pObj, i )
+ Saig_ManForEachLo( p0, pObj, i )
pObj->pData = Aig_ObjCreatePi( pNew );
- Saig_ManForEachLo( p2, pObj, i )
+ Saig_ManForEachLo( p1, pObj, i )
pObj->pData = Aig_ObjCreatePi( pNew );
// map internal nodes
- Aig_ManForEachNode( p1, pObj, i )
+ Aig_ManForEachNode( p0, pObj, i )
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
- Aig_ManForEachNode( p2, pObj, i )
+ Aig_ManForEachNode( p1, pObj, i )
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
// create primary outputs
- Saig_ManForEachPo( p1, pObj, i )
+ Saig_ManForEachPo( p0, pObj, i )
{
if ( Oper == 0 ) // XOR
- pObj = Aig_Exor( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild0Copy(Aig_ManPo(p2,i)) );
- else if ( Oper == 1 ) // implication is PO(p1) -> PO(p2) ... complement is PO(p1) & !PO(p2)
- pObj = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_Not(Aig_ObjChild0Copy(Aig_ManPo(p2,i))) );
+ pObj = Aig_Exor( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild0Copy(Aig_ManPo(p1,i)) );
+ else if ( Oper == 1 ) // implication is PO(p0) -> PO(p1) ... complement is PO(p0) & !PO(p1)
+ pObj = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_Not(Aig_ObjChild0Copy(Aig_ManPo(p1,i))) );
else
assert( 0 );
Aig_ObjCreatePo( pNew, pObj );
}
// create register inputs
- Saig_ManForEachLi( p1, pObj, i )
+ Saig_ManForEachLi( p0, pObj, i )
pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
- Saig_ManForEachLi( p2, pObj, i )
+ Saig_ManForEachLi( p1, pObj, i )
pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
// cleanup
- Aig_ManSetRegNum( pNew, Saig_ManRegNum(p1) + Saig_ManRegNum(p2) );
+ Aig_ManSetRegNum( pNew, Saig_ManRegNum(p0) + Saig_ManRegNum(p1) );
Aig_ManCleanup( pNew );
return pNew;
}
/**Function*************************************************************
- Synopsis [Duplicates the AIG to have constant-0 initial state.]
+ Synopsis [Creates combinational miter.]
Description []
@@ -100,30 +100,569 @@ Aig_Man_t * Saig_ManCreateMiter( Aig_Man_t * p1, Aig_Man_t * p2, int Oper )
SeeAlso []
***********************************************************************/
-Aig_Man_t * Saig_ManDupInitZero( Aig_Man_t * p )
+Aig_Man_t * Saig_ManCreateMiterComb( Aig_Man_t * p0, Aig_Man_t * p1, int Oper )
{
Aig_Man_t * pNew;
Aig_Obj_t * pObj;
int i;
+ assert( Aig_ManPiNum(p0) == Aig_ManPiNum(p1) );
+ assert( Aig_ManPoNum(p0) == Aig_ManPoNum(p1) );
+ pNew = Aig_ManStart( Aig_ManObjNumMax(p0) + Aig_ManObjNumMax(p1) );
+ pNew->pName = Aig_UtilStrsav( "miter" );
+ // map constant nodes
+ Aig_ManConst1(p0)->pData = Aig_ManConst1(pNew);
+ Aig_ManConst1(p1)->pData = Aig_ManConst1(pNew);
+ // map primary inputs and register outputs
+ Aig_ManForEachPi( p0, pObj, i )
+ pObj->pData = Aig_ObjCreatePi( pNew );
+ Aig_ManForEachPi( p1, pObj, i )
+ pObj->pData = Aig_ManPi( pNew, i );
+ // map internal nodes
+ Aig_ManForEachNode( p0, pObj, i )
+ pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
+ Aig_ManForEachNode( p1, pObj, i )
+ pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
+ // create primary outputs
+ Aig_ManForEachPo( p0, pObj, i )
+ {
+ if ( Oper == 0 ) // XOR
+ pObj = Aig_Exor( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild0Copy(Aig_ManPo(p1,i)) );
+ else if ( Oper == 1 ) // implication is PO(p0) -> PO(p1) ... complement is PO(p0) & !PO(p1)
+ pObj = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_Not(Aig_ObjChild0Copy(Aig_ManPo(p1,i))) );
+ else
+ assert( 0 );
+ Aig_ObjCreatePo( pNew, pObj );
+ }
+ // cleanup
+ Aig_ManSetRegNum( pNew, 0 );
+ Aig_ManCleanup( pNew );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Create combinational timeframes by unrolling sequential circuits.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Saig_ManUnrollTwo( Aig_Man_t * pBot, Aig_Man_t * pTop, int nFrames )
+{
+ Aig_Man_t * p, * pAig;
+ Aig_Obj_t * pObj, * pObjLi, * pObjLo;
+ int i, f;
+ assert( nFrames > 1 );
+ assert( Saig_ManPiNum(pBot) == Saig_ManPiNum(pTop) );
+ assert( Saig_ManPoNum(pBot) == Saig_ManPoNum(pTop) );
+ assert( Saig_ManRegNum(pBot) == Saig_ManRegNum(pTop) );
+ assert( Saig_ManRegNum(pBot) > 0 || Saig_ManRegNum(pTop) > 0 );
+ // start timeframes
+ p = Aig_ManStart( nFrames * AIG_MAX(Aig_ManObjNumMax(pBot), Aig_ManObjNumMax(pTop)) );
+ p->pName = Aig_UtilStrsav( "frames" );
+ // create variables for register outputs
+ pAig = pBot;
+ Saig_ManForEachLo( pAig, pObj, i )
+ pObj->pData = Aig_ObjCreatePi( p );
+ // add timeframes
+ for ( f = 0; f < nFrames; f++ )
+ {
+ // create PI nodes for this frame
+ Aig_ManConst1(pAig)->pData = Aig_ManConst1( p );
+ Saig_ManForEachPi( pAig, pObj, i )
+ pObj->pData = Aig_ObjCreatePi( p );
+ // add internal nodes of this frame
+ Aig_ManForEachNode( pAig, pObj, i )
+ pObj->pData = Aig_And( p, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
+ if ( f == nFrames - 1 )
+ {
+ // create POs for this frame
+ Aig_ManForEachPo( pAig, pObj, i )
+ Aig_ObjCreatePo( p, Aig_ObjChild0Copy(pObj) );
+ break;
+ }
+ // save register inputs
+ Saig_ManForEachLi( pAig, pObj, i )
+ pObj->pData = Aig_ObjChild0Copy(pObj);
+ // transfer to register outputs
+ Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i )
+ pObjLo->pData = pObjLi->pData;
+ if ( f == 0 )
+ {
+ // transfer from pOld to pNew
+ Saig_ManForEachLo( pAig, pObj, i )
+ Saig_ManLo(pTop, i)->pData = pObj->pData;
+ pAig = pTop;
+ }
+ }
+ Aig_ManCleanup( p );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG while creating POs from the set.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Aig_ManDupNodes_old( Aig_Man_t * p, Vec_Ptr_t * vSet )
+{
+ Aig_Man_t * pNew, * pCopy;
+ Aig_Obj_t * pObj;
+ int i;
pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
pNew->pName = Aig_UtilStrsav( p->pName );
Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
- Saig_ManForEachPi( p, pObj, i )
+ Aig_ManForEachPi( p, pObj, i )
pObj->pData = Aig_ObjCreatePi( pNew );
- Saig_ManForEachLo( p, pObj, i )
- pObj->pData = Aig_NotCond( Aig_ObjCreatePi( pNew ), pObj->fMarkA );
Aig_ManForEachNode( p, pObj, i )
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
- Saig_ManForEachPo( p, pObj, i )
- pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
+// Saig_ManForEachPo( p, pObj, i )
+// pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
+ Vec_PtrForEachEntry( vSet, pObj, i )
+ Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_Regular(pObj)->pData, Aig_IsComplement(pObj)) );
Saig_ManForEachLi( p, pObj, i )
- pObj->pData = Aig_ObjCreatePo( pNew, Aig_NotCond( Aig_ObjChild0Copy(pObj), pObj->fMarkA ) );
+ pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
Aig_ManSetRegNum( pNew, Saig_ManRegNum(p) );
- assert( Aig_ManNodeNum(pNew) == Aig_ManNodeNum(p) );
- return pNew;
+ // cleanup and return a copy
+ Aig_ManSeqCleanup( pNew );
+ pCopy = Aig_ManDupSimpleDfs( pNew );
+ Aig_ManStop( pNew );
+ return pCopy;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG while creating POs from the set.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Aig_ManDupNodes( Aig_Man_t * p, Vec_Ptr_t * vSet, int iPart )
+{
+ Aig_Man_t * pNew, * pCopy;
+ Aig_Obj_t * pObj;
+ int i;
+ Aig_ManCleanData( p );
+ pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
+ pNew->pName = Aig_UtilStrsav( p->pName );
+ Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
+ Saig_ManForEachPi( p, pObj, i )
+ pObj->pData = Aig_ObjCreatePi( pNew );
+ if ( iPart == 0 )
+ {
+ Saig_ManForEachLo( p, pObj, i )
+ if ( i < Saig_ManRegNum(p)/2 )
+ pObj->pData = Aig_ObjCreatePi( pNew );
+ }
+ else
+ {
+ Saig_ManForEachLo( p, pObj, i )
+ if ( i >= Saig_ManRegNum(p)/2 )
+ pObj->pData = Aig_ObjCreatePi( pNew );
+ }
+ Aig_ManForEachNode( p, pObj, i )
+ if ( Aig_ObjFanin0(pObj)->pData && Aig_ObjFanin1(pObj)->pData )
+ pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
+// Saig_ManForEachPo( p, pObj, i )
+// pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
+ Vec_PtrForEachEntry( vSet, pObj, i )
+ Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_Regular(pObj)->pData, Aig_IsComplement(pObj)) );
+ if ( iPart == 0 )
+ {
+ Saig_ManForEachLi( p, pObj, i )
+ if ( i < Saig_ManRegNum(p)/2 )
+ pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
+ }
+ else
+ {
+ Saig_ManForEachLi( p, pObj, i )
+ if ( i >= Saig_ManRegNum(p)/2 )
+ pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
+ }
+ Aig_ManSetRegNum( pNew, Saig_ManRegNum(p)/2 );
+ // cleanup and return a copy
+// Aig_ManSeqCleanup( pNew );
+ Aig_ManCleanup( pNew );
+ pCopy = Aig_ManDupSimpleDfs( pNew );
+ Aig_ManStop( pNew );
+ return pCopy;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG to have constant-0 initial state.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Saig_ManDemiterSimple( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 )
+{
+ Vec_Ptr_t * vSet0, * vSet1;
+ Aig_Obj_t * pObj, * pFanin, * pObj0, * pObj1;
+ int i, Counter = 0;
+ assert( Saig_ManRegNum(p) % 2 == 0 );
+ vSet0 = Vec_PtrAlloc( Saig_ManPoNum(p) );
+ vSet1 = Vec_PtrAlloc( Saig_ManPoNum(p) );
+ Saig_ManForEachPo( p, pObj, i )
+ {
+ pFanin = Aig_ObjFanin0(pObj);
+ if ( Aig_ObjIsConst1( pFanin ) )
+ {
+ if ( !Aig_ObjFaninC0(pObj) )
+ printf( "The output number %d of the miter is constant 1.\n", i );
+ Counter++;
+ continue;
+ }
+ if ( !Aig_ObjIsNode(pFanin) || !Aig_ObjRecognizeExor( pFanin, &pObj0, &pObj1 ) )
+ {
+ printf( "The miter cannot be demitered.\n" );
+ Vec_PtrFree( vSet0 );
+ Vec_PtrFree( vSet1 );
+ return 0;
+ }
+// printf( "%d %d ", Aig_Regular(pObj0)->Id, Aig_Regular(pObj1)->Id );
+ if ( Aig_Regular(pObj0)->Id < Aig_Regular(pObj1)->Id )
+ {
+ Vec_PtrPush( vSet0, pObj0 );
+ Vec_PtrPush( vSet1, pObj1 );
+ }
+ else
+ {
+ Vec_PtrPush( vSet0, pObj1 );
+ Vec_PtrPush( vSet1, pObj0 );
+ }
+ }
+// printf( "Miter has %d constant outputs.\n", Counter );
+// printf( "\n" );
+ if ( ppAig0 )
+ {
+ *ppAig0 = Aig_ManDupNodes( p, vSet0, 0 );
+ FREE( (*ppAig0)->pName );
+ (*ppAig0)->pName = Aig_UtilStrsav( "part0" );
+ }
+ if ( ppAig1 )
+ {
+ *ppAig1 = Aig_ManDupNodes( p, vSet1, 1 );
+ FREE( (*ppAig1)->pName );
+ (*ppAig1)->pName = Aig_UtilStrsav( "part1" );
+ }
+ Vec_PtrFree( vSet0 );
+ Vec_PtrFree( vSet1 );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Labels logic reachable from the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Saig_ManDemiterLabel_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int Value )
+{
+ if ( Aig_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Aig_ObjSetTravIdCurrent(p, pObj);
+ if ( Value )
+ pObj->fMarkB = 1;
+ else
+ pObj->fMarkA = 1;
+ if ( Saig_ObjIsPi(p, pObj) )
+ return;
+ if ( Saig_ObjIsLo(p, pObj) )
+ {
+ Saig_ManDemiterLabel_rec( p, Aig_ObjFanin0( Saig_ObjLoToLi(p, pObj) ), Value );
+ return;
+ }
+ assert( Aig_ObjIsNode(pObj) );
+ Saig_ManDemiterLabel_rec( p, Aig_ObjFanin0(pObj), Value );
+ Saig_ManDemiterLabel_rec( p, Aig_ObjFanin1(pObj), Value );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the first labeled register encountered during traversal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t * Saig_ManGetLabeledRegister_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
+{
+ Aig_Obj_t * pResult;
+ if ( Aig_ObjIsTravIdCurrent(p, pObj) )
+ return NULL;
+ Aig_ObjSetTravIdCurrent(p, pObj);
+ if ( Saig_ObjIsPi(p, pObj) )
+ return NULL;
+ if ( Saig_ObjIsLo(p, pObj) )
+ {
+ if ( pObj->fMarkA || pObj->fMarkB )
+ return pObj;
+ return Saig_ManGetLabeledRegister_rec( p, Aig_ObjFanin0( Saig_ObjLoToLi(p, pObj) ) );
+ }
+ assert( Aig_ObjIsNode(pObj) );
+ pResult = Saig_ManGetLabeledRegister_rec( p, Aig_ObjFanin0(pObj) );
+ if ( pResult )
+ return pResult;
+ return Saig_ManGetLabeledRegister_rec( p, Aig_ObjFanin1(pObj) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the AIG to have constant-0 initial state.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Saig_ManDemiter( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 )
+{
+ Vec_Ptr_t * vPairs, * vSet0, * vSet1;
+ Aig_Obj_t * pObj, * pObj0, * pObj1, * pFlop0, * pFlop1;
+ int i, Counter;
+ assert( Saig_ManRegNum(p) > 0 );
+ Aig_ManSetPioNumbers( p );
+ // check if demitering is possible
+ vPairs = Vec_PtrAlloc( 2 * Saig_ManPoNum(p) );
+ Saig_ManForEachPo( p, pObj, i )
+ {
+ if ( !Aig_ObjRecognizeExor( Aig_ObjFanin0(pObj), &pObj0, &pObj1 ) )
+ {
+ Vec_PtrFree( vPairs );
+ return 0;
+ }
+ Vec_PtrPush( vPairs, pObj0 );
+ Vec_PtrPush( vPairs, pObj1 );
+ }
+ // start array of outputs
+ vSet0 = Vec_PtrAlloc( Saig_ManPoNum(p) );
+ vSet1 = Vec_PtrAlloc( Saig_ManPoNum(p) );
+ // get the first pair of outputs
+ pObj0 = Vec_PtrEntry( vPairs, 0 );
+ pObj1 = Vec_PtrEntry( vPairs, 1 );
+ // label registers reachable from the outputs
+ Aig_ManIncrementTravId( p );
+ Saig_ManDemiterLabel_rec( p, Aig_Regular(pObj0), 0 );
+ Vec_PtrPush( vSet0, pObj0 );
+ Aig_ManIncrementTravId( p );
+ Saig_ManDemiterLabel_rec( p, Aig_Regular(pObj1), 1 );
+ Vec_PtrPush( vSet1, pObj1 );
+ // find where each output belongs
+ for ( i = 2; i < Vec_PtrSize(vPairs); i += 2 )
+ {
+ pObj0 = Vec_PtrEntry( vPairs, i );
+ pObj1 = Vec_PtrEntry( vPairs, i+1 );
+
+ Aig_ManIncrementTravId( p );
+ pFlop0 = Saig_ManGetLabeledRegister_rec( p, Aig_Regular(pObj0) );
+
+ Aig_ManIncrementTravId( p );
+ pFlop1 = Saig_ManGetLabeledRegister_rec( p, Aig_Regular(pObj1) );
+
+ if ( (pFlop0->fMarkA && pFlop0->fMarkB) || (pFlop1->fMarkA && pFlop1->fMarkB) ||
+ (pFlop0->fMarkA && pFlop1->fMarkA) || (pFlop0->fMarkB && pFlop1->fMarkB) )
+ printf( "Ouput pair %4d: Difficult case...\n", i/2 );
+
+ if ( pFlop0->fMarkB )
+ {
+ Saig_ManDemiterLabel_rec( p, pObj0, 1 );
+ Vec_PtrPush( vSet0, pObj0 );
+ }
+ else // if ( pFlop0->fMarkA ) or none
+ {
+ Saig_ManDemiterLabel_rec( p, pObj0, 0 );
+ Vec_PtrPush( vSet1, pObj0 );
+ }
+
+ if ( pFlop1->fMarkB )
+ {
+ Saig_ManDemiterLabel_rec( p, pObj1, 1 );
+ Vec_PtrPush( vSet0, pObj1 );
+ }
+ else // if ( pFlop1->fMarkA ) or none
+ {
+ Saig_ManDemiterLabel_rec( p, pObj1, 0 );
+ Vec_PtrPush( vSet1, pObj1 );
+ }
+ }
+ // check if there are any flops in common
+ Counter = 0;
+ Saig_ManForEachLo( p, pObj, i )
+ if ( pObj->fMarkA && pObj->fMarkB )
+ Counter++;
+ if ( Counter > 0 )
+ printf( "The miters contains %d flops reachable from both AIGs.\n", Counter );
+
+ // produce two miters
+ if ( ppAig0 )
+ {
+ assert( 0 );
+ *ppAig0 = Aig_ManDupNodes( p, vSet0, 0 ); // not ready
+ FREE( (*ppAig0)->pName );
+ (*ppAig0)->pName = Aig_UtilStrsav( "part0" );
+ }
+ if ( ppAig1 )
+ {
+ assert( 0 );
+ *ppAig1 = Aig_ManDupNodes( p, vSet1, 1 ); // not ready
+ FREE( (*ppAig1)->pName );
+ (*ppAig1)->pName = Aig_UtilStrsav( "part1" );
+ }
+ Vec_PtrFree( vSet0 );
+ Vec_PtrFree( vSet1 );
+ Vec_PtrFree( vPairs );
+ return 1;
}
+/**Function*************************************************************
+
+ Synopsis [Create specialized miter by unrolling two circuits.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Saig_ManCreateMiterTwo( Aig_Man_t * pOld, Aig_Man_t * pNew, int nFrames )
+{
+ Aig_Man_t * pFrames0, * pFrames1, * pMiter;
+ assert( Aig_ManNodeNum(pOld) <= Aig_ManNodeNum(pNew) );
+ pFrames0 = Saig_ManUnrollTwo( pOld, pOld, nFrames );
+ pFrames1 = Saig_ManUnrollTwo( pNew, pOld, nFrames );
+ pMiter = Saig_ManCreateMiterComb( pFrames0, pFrames1, 0 );
+ Aig_ManStop( pFrames0 );
+ Aig_ManStop( pFrames1 );
+ return pMiter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reduces SEC to CEC for the special case of seq synthesis.]
+
+ Description [The first circuit (pPart0) should be circuit before synthesis.
+ The second circuit (pPart1) should be circuit after synthesis.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SecSpecial( Aig_Man_t * pPart0, Aig_Man_t * pPart1, int fVerbose )
+{
+ extern int Fra_FraigCec( Aig_Man_t ** ppAig, int nConfLimit, int fVerbose );
+ int nFrames = 2; // modify to enable comparison over any number of frames
+ Aig_Man_t * pMiterCec;
+ int RetValue, clkTotal = clock();
+// assert( Aig_ManNodeNum(pPart0) <= Aig_ManNodeNum(pPart1) );
+ if ( Aig_ManNodeNum(pPart0) >= Aig_ManNodeNum(pPart1) )
+ {
+ printf( "Warning: The design after synthesis is smaller!\n" );
+ printf( "This warning may indicate that the order of designs is changed.\n" );
+ printf( "The solver expects the original disign as first argument and\n" );
+ printf( "the modified design as the second argument in Ssw_SecSpecial().\n" );
+ }
+ // create two-level miter
+ pMiterCec = Saig_ManCreateMiterTwo( pPart0, pPart1, nFrames );
+ if ( fVerbose )
+ {
+ Aig_ManPrintStats( pMiterCec );
+// Aig_ManDumpBlif( pMiterCec, "miter01.blif", NULL, NULL );
+// printf( "The new miter is written into file \"%s\".\n", "miter01.blif" );
+ }
+ // run CEC on this miter
+ RetValue = Fra_FraigCec( &pMiterCec, 100000, fVerbose );
+ // transfer model if given
+// if ( pNtk2 == NULL )
+// pNtk1->pModel = pMiterCec->pData, pMiterCec->pData = NULL;
+ Aig_ManStop( pMiterCec );
+ // report the miter
+ if ( RetValue == 1 )
+ {
+ printf( "Networks are equivalent. " );
+PRT( "Time", clock() - clkTotal );
+ }
+ else if ( RetValue == 0 )
+ {
+ printf( "Networks are NOT EQUIVALENT. " );
+PRT( "Time", clock() - clkTotal );
+ }
+ else
+ {
+ printf( "Networks are UNDECIDED. " );
+PRT( "Time", clock() - clkTotal );
+ }
+ fflush( stdout );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reduces SEC to CEC for the special case of seq synthesis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SecSpecialMiter( Aig_Man_t * pMiter, int fVerbose )
+{
+ Aig_Man_t * pPart0, * pPart1;
+ int RetValue;
+ if ( fVerbose )
+ Aig_ManPrintStats( pMiter );
+ // demiter the miter
+ if ( !Saig_ManDemiterSimple( pMiter, &pPart0, &pPart1 ) )
+ {
+ printf( "Demitering has failed.\n" );
+ return -1;
+ }
+ if ( fVerbose )
+ {
+ Aig_ManPrintStats( pPart0 );
+ Aig_ManPrintStats( pPart1 );
+// Aig_ManDumpBlif( pPart0, "part0.blif", NULL, NULL );
+// Aig_ManDumpBlif( pPart1, "part1.blif", NULL, NULL );
+// printf( "The result of demitering is written into files \"%s\" and \"%s\".\n", "part0.blif", "part1.blif" );
+ }
+ RetValue = Ssw_SecSpecial( pPart0, pPart1, fVerbose );
+ Aig_ManStop( pPart0 );
+ Aig_ManStop( pPart1 );
+ return RetValue;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/saig/saigSynch.c b/src/aig/saig/saigSynch.c
index 9dbbb420..eb0fefc9 100644
--- a/src/aig/saig/saigSynch.c
+++ b/src/aig/saig/saigSynch.c
@@ -453,6 +453,40 @@ Vec_Str_t * Saig_SynchSequence( Aig_Man_t * pAig, int nWords )
/**Function*************************************************************
+ Synopsis [Duplicates the AIG to have constant-0 initial state.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Saig_ManDupInitZero( Aig_Man_t * p )
+{
+ Aig_Man_t * pNew;
+ Aig_Obj_t * pObj;
+ int i;
+ pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
+ pNew->pName = Aig_UtilStrsav( p->pName );
+ Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
+ Saig_ManForEachPi( p, pObj, i )
+ pObj->pData = Aig_ObjCreatePi( pNew );
+ Saig_ManForEachLo( p, pObj, i )
+ pObj->pData = Aig_NotCond( Aig_ObjCreatePi( pNew ), pObj->fMarkA );
+ Aig_ManForEachNode( p, pObj, i )
+ pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
+ Saig_ManForEachPo( p, pObj, i )
+ pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
+ Saig_ManForEachLi( p, pObj, i )
+ pObj->pData = Aig_ObjCreatePo( pNew, Aig_NotCond( Aig_ObjChild0Copy(pObj), pObj->fMarkA ) );
+ Aig_ManSetRegNum( pNew, Saig_ManRegNum(p) );
+ assert( Aig_ManNodeNum(pNew) == Aig_ManNodeNum(p) );
+ return pNew;
+}
+
+/**Function*************************************************************
+
Synopsis [Determines synchronizing sequence using ternary simulation.]
Description []
diff --git a/src/aig/ssw/ssw.h b/src/aig/ssw/ssw.h
index 766407d4..e6e3a1b4 100644
--- a/src/aig/ssw/ssw.h
+++ b/src/aig/ssw/ssw.h
@@ -55,6 +55,7 @@ struct Ssw_Pars_t_
int fSemiFormal; // enable semiformal filtering
int fUniqueness; // enable uniqueness constraints
int fVerbose; // verbose stats
+ int fFlopVerbose; // verbose printout of redundant flops
// optimized latch correspondence
int fLatchCorrOpt; // perform register correspondence (optimized)
int nSatVarMax; // max number of SAT vars before recycling SAT solver (optimized latch corr only)
@@ -92,6 +93,8 @@ extern Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pP
extern Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
/*=== sswLoc.c ==========================================================*/
extern int Saig_ManLocalization( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose );
+/*=== sswMiter.c ===================================================*/
+extern int Ssw_SecSpecialMiter( Aig_Man_t * pMiter, int fVerbose );
/*=== sswPart.c ==========================================================*/
extern Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
/*=== sswPairs.c ===================================================*/
diff --git a/src/aig/ssw/sswPart.c b/src/aig/ssw/sswPart.c
index 7eb6b8fe..983a2022 100644
--- a/src/aig/ssw/sswPart.c
+++ b/src/aig/ssw/sswPart.c
@@ -97,12 +97,14 @@ Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
if ( pAig->vOnehots )
pTemp->vOnehots = Aig_ManRegProjectOnehots( pAig, pTemp, pAig->vOnehots, fVerbose );
// run SSW
- pNew = Ssw_SignalCorrespondence( pTemp, pPars );
- nClasses = Aig_TransferMappedClasses( pAig, pTemp, pMapBack );
- if ( fVerbose )
- printf( "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. It = %3d. Cl = %5d.\n",
- i, Vec_IntSize(vPart), Aig_ManPiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp), pPars->nIters, nClasses );
- Aig_ManStop( pNew );
+ if (nCountPis>0) {
+ pNew = Ssw_SignalCorrespondence( pTemp, pPars );
+ nClasses = Aig_TransferMappedClasses( pAig, pTemp, pMapBack );
+ if ( fVerbose )
+ printf( "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. It = %3d. Cl = %5d.\n",
+ i, Vec_IntSize(vPart), Aig_ManPiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp), pPars->nIters, nClasses );
+ Aig_ManStop( pNew );
+ }
Aig_ManStop( pTemp );
free( pMapBack );
}
diff --git a/src/aig/ssw_old/module.make b/src/aig/ssw_old/module.make
new file mode 100644
index 00000000..625d72d1
--- /dev/null
+++ b/src/aig/ssw_old/module.make
@@ -0,0 +1,14 @@
+SRC += src/aig/ssw/sswAig.c \
+ src/aig/ssw/sswBmc.c \
+ src/aig/ssw/sswClass.c \
+ src/aig/ssw/sswCnf.c \
+ src/aig/ssw/sswCore.c \
+ src/aig/ssw/sswLcorr.c \
+ src/aig/ssw/sswMan.c \
+ src/aig/ssw/sswPart.c \
+ src/aig/ssw/sswPairs.c \
+ src/aig/ssw/sswSat.c \
+ src/aig/ssw/sswSim.c \
+ src/aig/ssw/sswSimSat.c \
+ src/aig/ssw/sswSweep.c \
+ src/aig/ssw/sswUnique.c
diff --git a/src/aig/ssw_old/ssw.h b/src/aig/ssw_old/ssw.h
new file mode 100644
index 00000000..766407d4
--- /dev/null
+++ b/src/aig/ssw_old/ssw.h
@@ -0,0 +1,117 @@
+/**CFile****************************************************************
+
+ FileName [ssw.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: ssw.h,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __SSW_H__
+#define __SSW_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+// choicing parameters
+typedef struct Ssw_Pars_t_ Ssw_Pars_t;
+struct Ssw_Pars_t_
+{
+ int nPartSize; // size of the partition
+ int nOverSize; // size of the overlap between partitions
+ int nFramesK; // the induction depth
+ int nFramesAddSim; // the number of additional frames to simulate
+ int nConstrs; // treat the last nConstrs POs as seq constraints
+ int nMaxLevs; // the max number of levels of nodes to consider
+ int nBTLimit; // conflict limit at a node
+ int nMinDomSize; // min clock domain considered for optimization
+ int fPolarFlip; // uses polarity adjustment
+ int fSkipCheck; // do not run equivalence check for unaffected cones
+ int fLatchCorr; // perform register correspondence
+ int fSemiFormal; // enable semiformal filtering
+ int fUniqueness; // enable uniqueness constraints
+ int fVerbose; // verbose stats
+ // optimized latch correspondence
+ int fLatchCorrOpt; // perform register correspondence (optimized)
+ int nSatVarMax; // max number of SAT vars before recycling SAT solver (optimized latch corr only)
+ int nRecycleCalls; // calls to perform before recycling SAT solver (optimized latch corr only)
+ // internal parameters
+ int nIters; // the number of iterations performed
+};
+
+// sequential counter-example
+typedef struct Ssw_Cex_t_ Ssw_Cex_t;
+struct Ssw_Cex_t_
+{
+ int iPo; // the zero-based number of PO, for which verification failed
+ int iFrame; // the zero-based number of the time-frame, for which verificaiton failed
+ int nRegs; // the number of registers in the miter
+ int nPis; // the number of primary inputs in the miter
+ int nBits; // the number of words of bit data used
+ unsigned pData[0]; // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis)
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== sswAbs.c ==========================================================*/
+extern Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax, int fVerbose );
+/*=== sswCore.c ==========================================================*/
+extern void Ssw_ManSetDefaultParams( Ssw_Pars_t * p );
+extern void Ssw_ManSetDefaultParamsLcorr( Ssw_Pars_t * p );
+extern Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
+extern Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
+/*=== sswLoc.c ==========================================================*/
+extern int Saig_ManLocalization( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose );
+/*=== sswPart.c ==========================================================*/
+extern Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
+/*=== sswPairs.c ===================================================*/
+extern int Ssw_SecWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2, Ssw_Pars_t * pPars );
+extern int Ssw_SecGeneral( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Ssw_Pars_t * pPars );
+extern int Ssw_SecGeneralMiter( Aig_Man_t * pMiter, Ssw_Pars_t * pPars );
+/*=== sswSim.c ===================================================*/
+extern Ssw_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames );
+extern void Ssw_SmlFreeCounterExample( Ssw_Cex_t * pCex );
+extern int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p );
+extern int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p );
+extern Ssw_Cex_t * Ssw_SmlDupCounterExample( Ssw_Cex_t * p, int nRegsNew );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/aig/ssw_old/sswAig.c b/src/aig/ssw_old/sswAig.c
new file mode 100644
index 00000000..7b6d1bb0
--- /dev/null
+++ b/src/aig/ssw_old/sswAig.c
@@ -0,0 +1,205 @@
+/**CFile****************************************************************
+
+ FileName [sswAig.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [AIG manipulation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswAig.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs speculative reduction for one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Ssw_FramesConstrainNode( Ssw_Man_t * p, Aig_Man_t * pFrames, Aig_Man_t * pAig, Aig_Obj_t * pObj, int iFrame, int fTwoPos )
+{
+ Aig_Obj_t * pObjNew, * pObjNew2, * pObjRepr, * pObjReprNew, * pMiter;
+ // skip nodes without representative
+ pObjRepr = Aig_ObjRepr(pAig, pObj);
+ if ( pObjRepr == NULL )
+ return;
+ p->nConstrTotal++;
+ assert( pObjRepr->Id < pObj->Id );
+ // get the new node
+ pObjNew = Ssw_ObjFrame( p, pObj, iFrame );
+ // get the new node of the representative
+ pObjReprNew = Ssw_ObjFrame( p, pObjRepr, iFrame );
+ // if this is the same node, no need to add constraints
+ if ( pObj->fPhase == pObjRepr->fPhase )
+ {
+ assert( pObjNew != Aig_Not(pObjReprNew) );
+ if ( pObjNew == pObjReprNew )
+ return;
+ }
+ else
+ {
+ assert( pObjNew != pObjReprNew );
+ if ( pObjNew == Aig_Not(pObjReprNew) )
+ return;
+ }
+ p->nConstrReduced++;
+ // these are different nodes - perform speculative reduction
+ pObjNew2 = Aig_NotCond( pObjReprNew, pObj->fPhase ^ pObjRepr->fPhase );
+ // set the new node
+ Ssw_ObjSetFrame( p, pObj, iFrame, pObjNew2 );
+ // add the constraint
+ if ( fTwoPos )
+ {
+ Aig_ObjCreatePo( pFrames, pObjNew2 );
+ Aig_ObjCreatePo( pFrames, pObjNew );
+ }
+ else
+ {
+ pMiter = Aig_Exor( pFrames, pObjNew, pObjNew2 );
+ Aig_ObjCreatePo( pFrames, Aig_NotCond(pMiter, Aig_ObjPhaseReal(pMiter)) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the inductive case with speculative reduction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_FramesWithClasses( Ssw_Man_t * p )
+{
+ Aig_Man_t * pFrames;
+ Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjNew;
+ int i, f;
+ assert( p->pFrames == NULL );
+ assert( Aig_ManRegNum(p->pAig) > 0 );
+ assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) );
+ p->nConstrTotal = p->nConstrReduced = 0;
+
+ // start the fraig package
+ pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->nFrames );
+ // create latches for the first frame
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(pFrames) );
+ // add timeframes
+ for ( f = 0; f < p->pPars->nFramesK; f++ )
+ {
+ // map constants and PIs
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(pFrames) );
+ // set the constraints on the latch outputs
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, f, 1 );
+ // add internal nodes of this frame
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_And( pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, f, 1 );
+ }
+ // transfer latch input to the latch outputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ Ssw_ObjSetFrame( p, pObjLo, f+1, Ssw_ObjChild0Fra(p, pObjLi,f) );
+ }
+ // add the POs for the latch outputs of the last frame
+// Saig_ManForEachLo( p->pAig, pObj, i )
+// Aig_ObjCreatePo( pFrames, Ssw_ObjFrame( p, pObj, p->pPars->nFramesK ) );
+ for ( f = 0; f <= p->pPars->nFramesK; f++ )
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Aig_ObjCreatePo( pFrames, Ssw_ObjFrame( p, pObj, f ) );
+
+ // remove dangling nodes
+ Aig_ManCleanup( pFrames );
+ // make sure the satisfying assignment is node assigned
+ assert( pFrames->pData == NULL );
+//Aig_ManShow( pFrames, 0, NULL );
+ return pFrames;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the inductive case with speculative reduction.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p )
+{
+ Aig_Man_t * pFrames;
+ Aig_Obj_t * pObj, * pObjNew;
+ int i;
+ assert( p->pFrames == NULL );
+ assert( Aig_ManRegNum(p->pAig) > 0 );
+ assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) );
+ p->nConstrTotal = p->nConstrReduced = 0;
+
+ // start the fraig package
+ pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->nFrames );
+ // map constants and PIs
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), 0, Aig_ManConst1(pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(pFrames) );
+ // create latches for the first frame
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(pFrames) );
+ // set the constraints on the latch outputs
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, 0, 0 );
+ // add internal nodes of this frame
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_And( pFrames, Ssw_ObjChild0Fra(p, pObj, 0), Ssw_ObjChild1Fra(p, pObj, 0) );
+ Ssw_ObjSetFrame( p, pObj, 0, pObjNew );
+ Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, 0, 0 );
+ }
+ // add the POs for the latch outputs of the last frame
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ Aig_ObjCreatePo( pFrames, Ssw_ObjChild0Fra(p, pObj,0) );
+ // remove dangling nodes
+ Aig_ManCleanup( pFrames );
+ Aig_ManSetRegNum( pFrames, Aig_ManRegNum(p->pAig) );
+ printf( "SpecRed: Total constraints = %d. Reduced constraints = %d.\n",
+ p->nConstrTotal, p->nConstrReduced );
+ return pFrames;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ssw_old/sswBmc.c b/src/aig/ssw_old/sswBmc.c
new file mode 100644
index 00000000..e2d47440
--- /dev/null
+++ b/src/aig/ssw_old/sswBmc.c
@@ -0,0 +1,315 @@
+/**CFile****************************************************************
+
+ FileName [sswBmc.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Bounded model checker for equivalence clases.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswBmc.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Ssw_Bmc_t_ Ssw_Bmc_t; // BMC manager
+
+struct Ssw_Bmc_t_
+{
+ // parameters
+ int nConfMaxStart; // the starting conflict limit
+ int nConfMax; // the intermediate conflict limit
+ int nFramesSweep; // the number of frames to sweep
+ int fVerbose; // prints output statistics
+ // equivalences considered
+ Ssw_Man_t * pMan; // SAT sweeping manager
+ Vec_Ptr_t * vTargets; // the nodes that are watched
+ // storage for patterns
+ int nPatternsAlloc; // the max number of interesting states
+ int nPatterns; // the number of patterns
+ Vec_Ptr_t * vPatterns; // storage for the interesting states
+ Vec_Int_t * vHistory; // what state and how many steps
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Bmc_t * Ssw_BmcManStart( Ssw_Man_t * pMan, int nConfMax, int fVerbose )
+{
+ Ssw_Bmc_t * p;
+ Aig_Obj_t * pObj;
+ int i;
+ // create interpolation manager
+ p = ALLOC( Ssw_Bmc_t, 1 );
+ memset( p, 0, sizeof(Ssw_Bmc_t) );
+ p->nConfMaxStart = nConfMax;
+ p->nConfMax = nConfMax;
+ p->nFramesSweep = AIG_MAX( (1<<21)/Aig_ManNodeNum(pMan->pAig), pMan->nFrames );
+ p->fVerbose = fVerbose;
+ // equivalences considered
+ p->pMan = pMan;
+ p->vTargets = Vec_PtrAlloc( Saig_ManPoNum(p->pMan->pAig) );
+ Saig_ManForEachPo( p->pMan->pAig, pObj, i )
+ Vec_PtrPush( p->vTargets, Aig_ObjFanin0(pObj) );
+ // storage for patterns
+ p->nPatternsAlloc = 512;
+ p->nPatterns = 1;
+ p->vPatterns = Vec_PtrAllocSimInfo( Aig_ManRegNum(p->pMan->pAig), Aig_BitWordNum(p->nPatternsAlloc) );
+ Vec_PtrCleanSimInfo( p->vPatterns, 0, Aig_BitWordNum(p->nPatternsAlloc) );
+ p->vHistory = Vec_IntAlloc( 100 );
+ Vec_IntPush( p->vHistory, 0 );
+ // update arrays of the manager
+ free( p->pMan->pNodeToFrames );
+ Vec_IntFree( p->pMan->vSatVars );
+ p->pMan->pNodeToFrames = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pMan->pAig) * p->nFramesSweep );
+ p->pMan->vSatVars = Vec_IntStart( Aig_ManObjNumMax(p->pMan->pAig) * (p->nFramesSweep+1) );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_BmcManStop( Ssw_Bmc_t * p )
+{
+ Vec_PtrFree( p->vTargets );
+ Vec_PtrFree( p->vPatterns );
+ Vec_IntFree( p->vHistory );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_BmcCheckTargets( Ssw_Bmc_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ Vec_PtrForEachEntry( p->vTargets, pObj, i )
+ if ( !Ssw_ObjIsConst1Cand(p->pMan->pAig, pObj) )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManFilterBmcSavePattern( Ssw_Bmc_t * p )
+{
+ unsigned * pInfo;
+ Aig_Obj_t * pObj;
+ int i;
+ if ( p->nPatterns >= p->nPatternsAlloc )
+ return;
+ Saig_ManForEachLo( p->pMan->pAig, pObj, i )
+ {
+ pInfo = Vec_PtrEntry( p->vPatterns, i );
+ if ( Aig_InfoHasBit( p->pMan->pPatWords, Saig_ManPiNum(p->pMan->pAig) + i ) )
+ Aig_InfoSetBit( pInfo, p->nPatterns );
+ }
+ p->nPatterns++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManFilterBmc( Ssw_Bmc_t * pBmc, int iPat, int fCheckTargets )
+{
+ Ssw_Man_t * p = pBmc->pMan;
+ Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo;
+ unsigned * pInfo;
+ int i, f, clk, RetValue, fFirst = 0;
+clk = clock();
+
+ // start initialized timeframes
+ p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * 3 );
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ {
+ pInfo = Vec_PtrEntry( pBmc->vPatterns, i );
+ pObjNew = Aig_NotCond( Aig_ManConst1(p->pFrames), !Aig_InfoHasBit(pInfo, iPat) );
+ Ssw_ObjSetFrame( p, pObj, 0, pObjNew );
+ }
+
+ // sweep internal nodes
+ Ssw_ManStartSolver( p );
+ RetValue = pBmc->nFramesSweep;
+ for ( f = 0; f < pBmc->nFramesSweep; f++ )
+ {
+ // map constants and PIs
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(p->pFrames) );
+ // sweep internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ if ( Ssw_ManSweepNode( p, pObj, f, 1 ) )
+ {
+ Ssw_ManFilterBmcSavePattern( pBmc );
+ if ( fFirst == 0 )
+ {
+ fFirst = 1;
+ pBmc->nConfMax *= 10;
+ }
+ }
+ if ( f > 0 && p->pSat->stats.conflicts >= pBmc->nConfMax )
+ {
+ RetValue = -1;
+ break;
+ }
+ }
+ // quit if this is the last timeframe
+ if ( p->pSat->stats.conflicts >= pBmc->nConfMax )
+ {
+ RetValue += f + 1;
+ break;
+ }
+ if ( fCheckTargets && Ssw_BmcCheckTargets( pBmc ) )
+ break;
+ // transfer latch input to the latch outputs
+ // build logic cones for register outputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ {
+ pObjNew = Ssw_ObjChild0Fra(p, pObjLi,f);
+ Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew );
+ Ssw_CnfNodeAddToSolver( p, Aig_Regular(pObjNew) );
+ }
+//printf( "Frame %2d : Conflicts = %6d. \n", f, p->pSat->stats.conflicts );
+ }
+ if ( fFirst )
+ pBmc->nConfMax /= 10;
+
+ // cleanup
+ Ssw_ClassesCheck( p->ppClasses );
+p->timeBmc += clock() - clk;
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if one of the targets has failed.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_FilterUsingBmc( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int fVerbose )
+{
+ Ssw_Bmc_t * p;
+ int RetValue, Frames, Iter, clk = clock();
+ p = Ssw_BmcManStart( pMan, nConfMax, fVerbose );
+ if ( fCheckTargets && Ssw_BmcCheckTargets( p ) )
+ {
+ assert( 0 );
+ Ssw_BmcManStop( p );
+ return 1;
+ }
+ if ( fVerbose )
+ {
+ printf( "AIG : Const = %6d. Cl = %6d. Nodes = %6d. ConfMax = %6d. FramesMax = %6d.\n",
+ Ssw_ClassesCand1Num(p->pMan->ppClasses), Ssw_ClassesClassNum(p->pMan->ppClasses),
+ Aig_ManNodeNum(p->pMan->pAig), p->nConfMax, p->nFramesSweep );
+ }
+ RetValue = 0;
+ for ( Iter = 0; Iter < p->nPatterns; Iter++ )
+ {
+clk = clock();
+ Frames = Ssw_ManFilterBmc( p, Iter, fCheckTargets );
+ if ( fVerbose )
+ {
+ printf( "%3d : Const = %6d. Cl = %6d. NR = %6d. F = %3d. C = %5d. P = %3d. %s ",
+ Iter, Ssw_ClassesCand1Num(p->pMan->ppClasses), Ssw_ClassesClassNum(p->pMan->ppClasses),
+ Aig_ManNodeNum(p->pMan->pFrames), Frames, (int)p->pMan->pSat->stats.conflicts, p->nPatterns,
+ p->pMan->nSatFailsReal? "f" : " " );
+ PRT( "T", clock() - clk );
+ }
+ Ssw_ManCleanup( p->pMan );
+ if ( fCheckTargets && Ssw_BmcCheckTargets( p ) )
+ {
+ printf( "Target is hit!!!\n" );
+ RetValue = 1;
+ }
+ if ( p->nPatterns >= p->nPatternsAlloc )
+ break;
+ }
+ Ssw_BmcManStop( p );
+
+ pMan->nStrangers = 0;
+ pMan->nSatCalls = 0;
+ pMan->nSatProof = 0;
+ pMan->nSatFailsReal = 0;
+ pMan->nSatFailsTotal = 0;
+ pMan->nSatCallsUnsat = 0;
+ pMan->nSatCallsSat = 0;
+ pMan->timeSimSat = 0;
+ pMan->timeSat = 0;
+ pMan->timeSatSat = 0;
+ pMan->timeSatUnsat = 0;
+ pMan->timeSatUndec = 0;
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ssw_old/sswClass.c b/src/aig/ssw_old/sswClass.c
new file mode 100644
index 00000000..cfbb138c
--- /dev/null
+++ b/src/aig/ssw_old/sswClass.c
@@ -0,0 +1,941 @@
+/**CFile****************************************************************
+
+ FileName [sswClass.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Representation of candidate equivalence classes.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswClass.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+/*
+ The candidate equivalence classes are stored as a vector of pointers
+ to the array of pointers to the nodes in each class.
+ The first node of the class is its representative node.
+ The representative has the smallest topological order among the class nodes.
+ The nodes inside each class are ordered according to their topological order.
+ The classes are ordered according to the topo order of their representatives.
+*/
+
+// internal representation of candidate equivalence classes
+struct Ssw_Cla_t_
+{
+ // class information
+ Aig_Man_t * pAig; // original AIG manager
+ Aig_Obj_t *** pId2Class; // non-const classes by ID of repr node
+ int * pClassSizes; // sizes of each equivalence class
+ // statistics
+ int nClasses; // the total number of non-const classes
+ int nCands1; // the total number of const candidates
+ int nLits; // the number of literals in all classes
+ // memory
+ Aig_Obj_t ** pMemClasses; // memory allocated for equivalence classes
+ Aig_Obj_t ** pMemClassesFree; // memory allocated for equivalence classes to be used
+ // temporary data
+ Vec_Ptr_t * vClassOld; // old equivalence class after splitting
+ Vec_Ptr_t * vClassNew; // new equivalence class(es) after splitting
+ Vec_Ptr_t * vRefined; // the nodes refined since the last iteration
+ // procedures used for class refinement
+ void * pManData;
+ unsigned (*pFuncNodeHash) (void *,Aig_Obj_t *); // returns hash key of the node
+ int (*pFuncNodeIsConst) (void *,Aig_Obj_t *); // returns 1 if the node is a constant
+ int (*pFuncNodesAreEqual) (void *,Aig_Obj_t *, Aig_Obj_t *); // returns 1 if nodes are equal up to a complement
+};
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline Aig_Obj_t * Ssw_ObjNext( Aig_Obj_t ** ppNexts, Aig_Obj_t * pObj ) { return ppNexts[pObj->Id]; }
+static inline void Ssw_ObjSetNext( Aig_Obj_t ** ppNexts, Aig_Obj_t * pObj, Aig_Obj_t * pNext ) { ppNexts[pObj->Id] = pNext; }
+
+// iterator through the equivalence classes
+#define Ssw_ManForEachClass( p, ppClass, i ) \
+ for ( i = 0; i < Aig_ManObjNumMax(p->pAig); i++ ) \
+ if ( ((ppClass) = p->pId2Class[i]) == NULL ) {} else
+// iterator through the nodes in one class
+#define Ssw_ClassForEachNode( p, pRepr, pNode, i ) \
+ for ( i = 0; i < p->pClassSizes[pRepr->Id]; i++ ) \
+ if ( ((pNode) = p->pId2Class[pRepr->Id][i]) == NULL ) {} else
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates one equivalence class.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Ssw_ObjAddClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, Aig_Obj_t ** pClass, int nSize )
+{
+ assert( p->pId2Class[pRepr->Id] == NULL );
+ assert( pClass[0] == pRepr );
+ p->pId2Class[pRepr->Id] = pClass;
+ assert( p->pClassSizes[pRepr->Id] == 0 );
+ assert( nSize > 1 );
+ p->pClassSizes[pRepr->Id] = nSize;
+ p->nClasses++;
+ p->nLits += nSize - 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Removes one equivalence class.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Aig_Obj_t ** Ssw_ObjRemoveClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr )
+{
+ Aig_Obj_t ** pClass = p->pId2Class[pRepr->Id];
+ int nSize;
+ assert( pClass != NULL );
+ p->pId2Class[pRepr->Id] = NULL;
+ nSize = p->pClassSizes[pRepr->Id];
+ assert( nSize > 1 );
+ p->nClasses--;
+ p->nLits -= nSize - 1;
+ p->pClassSizes[pRepr->Id] = 0;
+ return pClass;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cla_t * Ssw_ClassesStart( Aig_Man_t * pAig )
+{
+ Ssw_Cla_t * p;
+ p = ALLOC( Ssw_Cla_t, 1 );
+ memset( p, 0, sizeof(Ssw_Cla_t) );
+ p->pAig = pAig;
+ p->pId2Class = CALLOC( Aig_Obj_t **, Aig_ManObjNumMax(pAig) );
+ p->pClassSizes = CALLOC( int, Aig_ManObjNumMax(pAig) );
+ p->vClassOld = Vec_PtrAlloc( 100 );
+ p->vClassNew = Vec_PtrAlloc( 100 );
+ p->vRefined = Vec_PtrAlloc( 1000 );
+ assert( pAig->pReprs == NULL );
+ Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesSetData( Ssw_Cla_t * p, void * pManData,
+ unsigned (*pFuncNodeHash)(void *,Aig_Obj_t *), // returns hash key of the node
+ int (*pFuncNodeIsConst)(void *,Aig_Obj_t *), // returns 1 if the node is a constant
+ int (*pFuncNodesAreEqual)(void *,Aig_Obj_t *, Aig_Obj_t *) ) // returns 1 if nodes are equal up to a complement
+{
+ p->pManData = pManData;
+ p->pFuncNodeHash = pFuncNodeHash;
+ p->pFuncNodeIsConst = pFuncNodeIsConst;
+ p->pFuncNodesAreEqual = pFuncNodesAreEqual;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesStop( Ssw_Cla_t * p )
+{
+ if ( p->vClassNew ) Vec_PtrFree( p->vClassNew );
+ if ( p->vClassOld ) Vec_PtrFree( p->vClassOld );
+ Vec_PtrFree( p->vRefined );
+ FREE( p->pId2Class );
+ FREE( p->pClassSizes );
+ FREE( p->pMemClasses );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_ClassesReadAig( Ssw_Cla_t * p )
+{
+ return p->pAig;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Ptr_t * Ssw_ClassesGetRefined( Ssw_Cla_t * p )
+{
+ return p->vRefined;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesClearRefined( Ssw_Cla_t * p )
+{
+ Vec_PtrClear( p->vRefined );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesCand1Num( Ssw_Cla_t * p )
+{
+ return p->nCands1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesClassNum( Ssw_Cla_t * p )
+{
+ return p->nClasses;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesLitNum( Ssw_Cla_t * p )
+{
+ return p->nLits;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Obj_t ** Ssw_ClassesReadClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, int * pnSize )
+{
+ if ( p->pId2Class[pRepr->Id] == NULL )
+ return NULL;
+ assert( p->pId2Class[pRepr->Id] != NULL );
+ assert( p->pClassSizes[pRepr->Id] > 1 );
+ *pnSize = p->pClassSizes[pRepr->Id];
+ return p->pId2Class[pRepr->Id];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stop representation of equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesCollectClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, Vec_Ptr_t * vClass )
+{
+ int i;
+ Vec_PtrClear( vClass );
+ if ( p->pId2Class[pRepr->Id] == NULL )
+ return;
+ assert( p->pClassSizes[pRepr->Id] > 1 );
+ for ( i = 1; i < p->pClassSizes[pRepr->Id]; i++ )
+ Vec_PtrPush( vClass, p->pId2Class[pRepr->Id][i] );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Checks candidate equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesCheck( Ssw_Cla_t * p )
+{
+ Aig_Obj_t * pObj, * pPrev, ** ppClass;
+ int i, k, nLits, nClasses, nCands1;
+ nClasses = nLits = 0;
+ Ssw_ManForEachClass( p, ppClass, k )
+ {
+ pPrev = NULL;
+ assert( p->pClassSizes[ppClass[0]->Id] >= 2 );
+ Ssw_ClassForEachNode( p, ppClass[0], pObj, i )
+ {
+ if ( i == 0 )
+ assert( Aig_ObjRepr(p->pAig, pObj) == NULL );
+ else
+ {
+ assert( Aig_ObjRepr(p->pAig, pObj) == ppClass[0] );
+ assert( pPrev->Id < pObj->Id );
+ nLits++;
+ }
+ pPrev = pObj;
+ }
+ nClasses++;
+ }
+ nCands1 = 0;
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ nCands1 += Ssw_ObjIsConst1Cand( p->pAig, pObj );
+ assert( p->nLits == nLits );
+ assert( p->nCands1 == nCands1 );
+ assert( p->nClasses == nClasses );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints simulation classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesPrintOne( Ssw_Cla_t * p, Aig_Obj_t * pRepr )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ printf( "{ " );
+ Ssw_ClassForEachNode( p, pRepr, pObj, i )
+ printf( "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) );
+ printf( "}\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints simulation classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesPrint( Ssw_Cla_t * p, int fVeryVerbose )
+{
+ Aig_Obj_t ** ppClass;
+ Aig_Obj_t * pObj;
+ int i;
+ printf( "Equivalence classes: Const1 = %5d. Class = %5d. Lit = %5d.\n",
+ p->nCands1, p->nClasses, p->nCands1+p->nLits );
+ if ( !fVeryVerbose )
+ return;
+ printf( "Constants { " );
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) )
+ printf( "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) );
+ printf( "}\n" );
+ Ssw_ManForEachClass( p, ppClass, i )
+ {
+ printf( "%3d (%3d) : ", i, p->pClassSizes[i] );
+ Ssw_ClassesPrintOne( p, ppClass[0] );
+ }
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints simulation classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ClassesRemoveNode( Ssw_Cla_t * p, Aig_Obj_t * pObj )
+{
+ Aig_Obj_t * pRepr, * pTemp;
+ assert( p->pClassSizes[pObj->Id] == 0 );
+ assert( p->pId2Class[pObj->Id] == NULL );
+ pRepr = Aig_ObjRepr( p->pAig, pObj );
+ assert( pRepr != NULL );
+ Vec_PtrPush( p->vRefined, pObj );
+ if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) )
+ {
+ assert( p->pClassSizes[pRepr->Id] == 0 );
+ assert( p->pId2Class[pRepr->Id] == NULL );
+ Aig_ObjSetRepr( p->pAig, pObj, NULL );
+ p->nCands1--;
+ return;
+ }
+ Vec_PtrPush( p->vRefined, pRepr );
+ Aig_ObjSetRepr( p->pAig, pObj, NULL );
+ assert( p->pId2Class[pRepr->Id][0] == pRepr );
+ assert( p->pClassSizes[pRepr->Id] >= 2 );
+ if ( p->pClassSizes[pRepr->Id] == 2 )
+ {
+ p->pId2Class[pRepr->Id] = NULL;
+ p->nClasses--;
+ p->pClassSizes[pRepr->Id] = 0;
+ p->nLits--;
+ }
+ else
+ {
+ int i, k = 0;
+ // remove the entry from the class
+ Ssw_ClassForEachNode( p, pRepr, pTemp, i )
+ if ( pTemp != pObj )
+ p->pId2Class[pRepr->Id][k++] = pTemp;
+ assert( k + 1 == p->pClassSizes[pRepr->Id] );
+ // reduce the class
+ p->pClassSizes[pRepr->Id]--;
+ p->nLits--;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates initial simulation classes.]
+
+ Description [Assumes that simulation info is assigned.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs, int fVerbose )
+{
+ Ssw_Cla_t * p;
+ Ssw_Sml_t * pSml;
+ Aig_Obj_t ** ppTable, ** ppNexts, ** ppClassNew;
+ Aig_Obj_t * pObj, * pTemp, * pRepr;
+ int i, k, nTableSize, nNodes, iEntry, nEntries, nEntries2;
+ int clk;
+
+ // start the classes
+ p = Ssw_ClassesStart( pAig );
+
+ // perform sequential simulation
+clk = clock();
+ pSml = Ssw_SmlSimulateSeq( pAig, 0, 32, 4 );
+if ( fVerbose )
+{
+PRT( "Simulation of 32 frames with 4 words", clock() - clk );
+}
+
+ // set comparison procedures
+clk = clock();
+ Ssw_ClassesSetData( p, pSml, Ssw_SmlObjHashWord, Ssw_SmlObjIsConstWord, Ssw_SmlObjsAreEqualWord );
+
+ // allocate the hash table hashing simulation info into nodes
+ nTableSize = Aig_PrimeCudd( Aig_ManObjNumMax(p->pAig)/4 );
+ ppTable = CALLOC( Aig_Obj_t *, nTableSize );
+ ppNexts = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pAig) );
+
+ // add all the nodes to the hash table
+ nEntries = 0;
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ {
+ if ( fLatchCorr )
+ {
+ if ( !Saig_ObjIsLo(p->pAig, pObj) )
+ continue;
+ }
+ else
+ {
+ if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) )
+ continue;
+ // skip the node with more that the given number of levels
+ if ( nMaxLevs && (int)pObj->Level > nMaxLevs )
+ continue;
+ }
+ // check if the node belongs to the class of constant 1
+ if ( p->pFuncNodeIsConst( p->pManData, pObj ) )
+ {
+ Ssw_ObjSetConst1Cand( p->pAig, pObj );
+ p->nCands1++;
+ continue;
+ }
+ // hash the node by its simulation info
+ iEntry = p->pFuncNodeHash( p->pManData, pObj ) % nTableSize;
+ // add the node to the class
+ if ( ppTable[iEntry] == NULL )
+ ppTable[iEntry] = pObj;
+ else
+ {
+ // set the representative of this node
+ pRepr = ppTable[iEntry];
+ Aig_ObjSetRepr( p->pAig, pObj, pRepr );
+ // add node to the table
+ if ( Ssw_ObjNext( ppNexts, pRepr ) == NULL )
+ { // this will be the second entry
+ p->pClassSizes[pRepr->Id]++;
+ nEntries++;
+ }
+ // add the entry to the list
+ Ssw_ObjSetNext( ppNexts, pObj, Ssw_ObjNext( ppNexts, pRepr ) );
+ Ssw_ObjSetNext( ppNexts, pRepr, pObj );
+ p->pClassSizes[pRepr->Id]++;
+ nEntries++;
+ }
+ }
+
+ // allocate room for classes
+ p->pMemClasses = ALLOC( Aig_Obj_t *, nEntries + p->nCands1 );
+ p->pMemClassesFree = p->pMemClasses + nEntries;
+
+ // copy the entries into storage in the topological order
+ nEntries2 = 0;
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ {
+ if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) )
+ continue;
+ nNodes = p->pClassSizes[pObj->Id];
+ // skip the nodes that are not representatives of non-trivial classes
+ if ( nNodes == 0 )
+ continue;
+ assert( nNodes > 1 );
+ // add the nodes to the class in the topological order
+ ppClassNew = p->pMemClasses + nEntries2;
+ ppClassNew[0] = pObj;
+ for ( pTemp = Ssw_ObjNext(ppNexts, pObj), k = 1; pTemp;
+ pTemp = Ssw_ObjNext(ppNexts, pTemp), k++ )
+ {
+ ppClassNew[nNodes-k] = pTemp;
+ }
+ // add the class of nodes
+ p->pClassSizes[pObj->Id] = 0;
+ Ssw_ObjAddClass( p, pObj, ppClassNew, nNodes );
+ // increment the number of entries
+ nEntries2 += nNodes;
+ }
+ assert( nEntries == nEntries2 );
+ free( ppTable );
+ free( ppNexts );
+
+ // now it is time to refine the classes
+ Ssw_ClassesRefine( p, 1 );
+ Ssw_ClassesCheck( p );
+ Ssw_SmlStop( pSml );
+// Ssw_ClassesPrint( p, 0 );
+if ( fVerbose )
+{
+PRT( "Collecting candidate equival classes", clock() - clk );
+}
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates initial simulation classes.]
+
+ Description [Assumes that simulation info is assigned.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cla_t * Ssw_ClassesPrepareSimple( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs )
+{
+ Ssw_Cla_t * p;
+ Aig_Obj_t * pObj;
+ int i;
+ // start the classes
+ p = Ssw_ClassesStart( pAig );
+ // go through the nodes
+ p->nCands1 = 0;
+ Aig_ManForEachObj( pAig, pObj, i )
+ {
+ if ( fLatchCorr )
+ {
+ if ( !Saig_ObjIsLo(pAig, pObj) )
+ continue;
+ }
+ else
+ {
+ if ( !Aig_ObjIsNode(pObj) && !Saig_ObjIsLo(pAig, pObj) )
+ continue;
+ // skip the node with more that the given number of levels
+ if ( nMaxLevs && (int)pObj->Level > nMaxLevs )
+ continue;
+ }
+ Ssw_ObjSetConst1Cand( pAig, pObj );
+ p->nCands1++;
+ }
+ // allocate room for classes
+ p->pMemClassesFree = p->pMemClasses = ALLOC( Aig_Obj_t *, p->nCands1 );
+// Ssw_ClassesPrint( p, 0 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates initial simulation classes.]
+
+ Description [Assumes that simulation info is assigned.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cla_t * Ssw_ClassesPrepareTargets( Aig_Man_t * pAig )
+{
+ Ssw_Cla_t * p;
+ Aig_Obj_t * pObj;
+ int i;
+ // start the classes
+ p = Ssw_ClassesStart( pAig );
+ // go through the nodes
+ p->nCands1 = 0;
+ Saig_ManForEachPo( pAig, pObj, i )
+ {
+ Ssw_ObjSetConst1Cand( pAig, Aig_ObjFanin0(pObj) );
+ p->nCands1++;
+ }
+ // allocate room for classes
+ p->pMemClassesFree = p->pMemClasses = ALLOC( Aig_Obj_t *, p->nCands1 );
+// Ssw_ClassesPrint( p, 0 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates classes from the temporary representation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cla_t * Ssw_ClassesPreparePairs( Aig_Man_t * pAig, Vec_Int_t ** pvClasses )
+{
+ Ssw_Cla_t * p;
+ Aig_Obj_t ** ppClassNew;
+ Aig_Obj_t * pObj, * pRepr, * pPrev;
+ int i, k, nTotalObjs, nEntries, Entry;
+ // start the classes
+ p = Ssw_ClassesStart( pAig );
+ // count the number of entries in the classes
+ nTotalObjs = 0;
+ for ( i = 0; i < Aig_ManObjNumMax(pAig); i++ )
+ nTotalObjs += pvClasses[i] ? Vec_IntSize(pvClasses[i]) : 0;
+ // allocate memory for classes
+ p->pMemClasses = ALLOC( Aig_Obj_t *, nTotalObjs );
+ // create constant-1 class
+ if ( pvClasses[0] )
+ Vec_IntForEachEntry( pvClasses[0], Entry, i )
+ {
+ assert( (i == 0) == (Entry == 0) );
+ if ( i == 0 )
+ continue;
+ pObj = Aig_ManObj( pAig, Entry );
+ Ssw_ObjSetConst1Cand( pAig, pObj );
+ p->nCands1++;
+ }
+ // create classes
+ nEntries = 0;
+ for ( i = 1; i < Aig_ManObjNumMax(pAig); i++ )
+ {
+ if ( pvClasses[i] == NULL )
+ continue;
+ // get room for storing the class
+ ppClassNew = p->pMemClasses + nEntries;
+ nEntries += Vec_IntSize( pvClasses[i] );
+ // store the nodes of the class
+ pPrev = pRepr = Aig_ManObj( pAig, Vec_IntEntry(pvClasses[i],0) );
+ ppClassNew[0] = pRepr;
+ Vec_IntForEachEntryStart( pvClasses[i], Entry, k, 1 )
+ {
+ pObj = Aig_ManObj( pAig, Entry );
+ assert( pPrev->Id < pObj->Id );
+ pPrev = pObj;
+ ppClassNew[k] = pObj;
+ Aig_ObjSetRepr( pAig, pObj, pRepr );
+ }
+ // create new class
+ Ssw_ObjAddClass( p, pRepr, ppClassNew, Vec_IntSize(pvClasses[i]) );
+ }
+ // prepare room for new classes
+ p->pMemClassesFree = p->pMemClasses + nEntries;
+ Ssw_ClassesCheck( p );
+// Ssw_ClassesPrint( p, 0 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Iteratively refines the classes after simulation.]
+
+ Description [Returns the number of refinements performed.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesRefineOneClass( Ssw_Cla_t * p, Aig_Obj_t * pReprOld, int fRecursive )
+{
+ Aig_Obj_t ** pClassOld, ** pClassNew;
+ Aig_Obj_t * pObj, * pReprNew;
+ int i;
+
+ // split the class
+ Vec_PtrClear( p->vClassOld );
+ Vec_PtrClear( p->vClassNew );
+ Ssw_ClassForEachNode( p, pReprOld, pObj, i )
+ if ( p->pFuncNodesAreEqual(p->pManData, pReprOld, pObj) )
+ Vec_PtrPush( p->vClassOld, pObj );
+ else
+ Vec_PtrPush( p->vClassNew, pObj );
+ // check if splitting happened
+ if ( Vec_PtrSize(p->vClassNew) == 0 )
+ return 0;
+ // remember that this class is refined
+ Ssw_ClassForEachNode( p, pReprOld, pObj, i )
+ Vec_PtrPush( p->vRefined, pObj );
+
+ // get the new representative
+ pReprNew = Vec_PtrEntry( p->vClassNew, 0 );
+ assert( Vec_PtrSize(p->vClassOld) > 0 );
+ assert( Vec_PtrSize(p->vClassNew) > 0 );
+
+ // create old class
+ pClassOld = Ssw_ObjRemoveClass( p, pReprOld );
+ Vec_PtrForEachEntry( p->vClassOld, pObj, i )
+ {
+ pClassOld[i] = pObj;
+ Aig_ObjSetRepr( p->pAig, pObj, i? pReprOld : NULL );
+ }
+ // create new class
+ pClassNew = pClassOld + i;
+ Vec_PtrForEachEntry( p->vClassNew, pObj, i )
+ {
+ pClassNew[i] = pObj;
+ Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL );
+ }
+
+ // put classes back
+ if ( Vec_PtrSize(p->vClassOld) > 1 )
+ Ssw_ObjAddClass( p, pReprOld, pClassOld, Vec_PtrSize(p->vClassOld) );
+ if ( Vec_PtrSize(p->vClassNew) > 1 )
+ Ssw_ObjAddClass( p, pReprNew, pClassNew, Vec_PtrSize(p->vClassNew) );
+
+ // check if the class should be recursively refined
+ if ( fRecursive && Vec_PtrSize(p->vClassNew) > 1 )
+ return 1 + Ssw_ClassesRefineOneClass( p, pReprNew, 1 );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refines the classes after simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesRefine( Ssw_Cla_t * p, int fRecursive )
+{
+ Aig_Obj_t ** ppClass;
+ int i, nRefis = 0;
+ Ssw_ManForEachClass( p, ppClass, i )
+ nRefis += Ssw_ClassesRefineOneClass( p, ppClass[0], fRecursive );
+ return nRefis;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refine the group of constant 1 nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesRefineConst1Group( Ssw_Cla_t * p, Vec_Ptr_t * vRoots, int fRecursive )
+{
+ Aig_Obj_t * pObj, * pReprNew, ** ppClassNew;
+ int i;
+ if ( Vec_PtrSize(vRoots) == 0 )
+ return 0;
+ // collect the nodes to be refined
+ Vec_PtrClear( p->vClassNew );
+ Vec_PtrForEachEntry( vRoots, pObj, i )
+ if ( !p->pFuncNodeIsConst( p->pManData, pObj ) )
+ Vec_PtrPush( p->vClassNew, pObj );
+ // check if there is a new class
+ if ( Vec_PtrSize(p->vClassNew) == 0 )
+ return 0;
+ p->nCands1 -= Vec_PtrSize(p->vClassNew);
+ pReprNew = Vec_PtrEntry( p->vClassNew, 0 );
+ Aig_ObjSetRepr( p->pAig, pReprNew, NULL );
+ if ( Vec_PtrSize(p->vClassNew) == 1 )
+ return 1;
+ // create a new class composed of these nodes
+ ppClassNew = p->pMemClassesFree;
+ p->pMemClassesFree += Vec_PtrSize(p->vClassNew);
+ Vec_PtrForEachEntry( p->vClassNew, pObj, i )
+ {
+ ppClassNew[i] = pObj;
+ Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL );
+ }
+ Ssw_ObjAddClass( p, pReprNew, ppClassNew, Vec_PtrSize(p->vClassNew) );
+ // refine them recursively
+ if ( fRecursive )
+ return 1 + Ssw_ClassesRefineOneClass( p, pReprNew, 1 );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Refine the group of constant 1 nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ClassesRefineConst1( Ssw_Cla_t * p, int fRecursive )
+{
+ Aig_Obj_t * pObj, * pReprNew, ** ppClassNew;
+ int i;
+ // collect the nodes to be refined
+ Vec_PtrClear( p->vClassNew );
+ for ( i = 0; i < Vec_PtrSize(p->pAig->vObjs); i++ )
+ if ( p->pAig->pReprs[i] == Aig_ManConst1(p->pAig) )
+ {
+ pObj = Aig_ManObj( p->pAig, i );
+ if ( !p->pFuncNodeIsConst( p->pManData, pObj ) )
+ {
+ Vec_PtrPush( p->vClassNew, pObj );
+ Vec_PtrPush( p->vRefined, pObj );
+ }
+ }
+ // check if there is a new class
+ if ( Vec_PtrSize(p->vClassNew) == 0 )
+ return 0;
+ p->nCands1 -= Vec_PtrSize(p->vClassNew);
+ pReprNew = Vec_PtrEntry( p->vClassNew, 0 );
+ Aig_ObjSetRepr( p->pAig, pReprNew, NULL );
+ if ( Vec_PtrSize(p->vClassNew) == 1 )
+ return 1;
+ // create a new class composed of these nodes
+ ppClassNew = p->pMemClassesFree;
+ p->pMemClassesFree += Vec_PtrSize(p->vClassNew);
+ Vec_PtrForEachEntry( p->vClassNew, pObj, i )
+ {
+ ppClassNew[i] = pObj;
+ Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL );
+ }
+ Ssw_ObjAddClass( p, pReprNew, ppClassNew, Vec_PtrSize(p->vClassNew) );
+ // refine them recursively
+ if ( fRecursive )
+ return 1 + Ssw_ClassesRefineOneClass( p, pReprNew, 1 );
+ return 1;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ssw_old/sswCnf.c b/src/aig/ssw_old/sswCnf.c
new file mode 100644
index 00000000..e4b8f9f6
--- /dev/null
+++ b/src/aig/ssw_old/sswCnf.c
@@ -0,0 +1,335 @@
+/**CFile****************************************************************
+
+ FileName [sswCnf.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Computation of CNF.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswCnf.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Addes clauses to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode )
+{
+ Aig_Obj_t * pNodeI, * pNodeT, * pNodeE;
+ int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE;
+
+ assert( !Aig_IsComplement( pNode ) );
+ assert( Aig_ObjIsMuxType( pNode ) );
+ // get nodes (I = if, T = then, E = else)
+ pNodeI = Aig_ObjRecognizeMux( pNode, &pNodeT, &pNodeE );
+ // get the variable numbers
+ VarF = Ssw_ObjSatNum(p,pNode);
+ VarI = Ssw_ObjSatNum(p,pNodeI);
+ VarT = Ssw_ObjSatNum(p,Aig_Regular(pNodeT));
+ VarE = Ssw_ObjSatNum(p,Aig_Regular(pNodeE));
+ // get the complementation flags
+ fCompT = Aig_IsComplement(pNodeT);
+ fCompE = Aig_IsComplement(pNodeE);
+
+ // f = ITE(i, t, e)
+
+ // i' + t' + f
+ // i' + t + f'
+ // i + e' + f
+ // i + e + f'
+
+ // create four clauses
+ pLits[0] = toLitCond(VarI, 1);
+ pLits[1] = toLitCond(VarT, 1^fCompT);
+ pLits[2] = toLitCond(VarF, 0);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Aig_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
+ assert( RetValue );
+ pLits[0] = toLitCond(VarI, 1);
+ pLits[1] = toLitCond(VarT, 0^fCompT);
+ pLits[2] = toLitCond(VarF, 1);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Aig_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
+ assert( RetValue );
+ pLits[0] = toLitCond(VarI, 0);
+ pLits[1] = toLitCond(VarE, 1^fCompE);
+ pLits[2] = toLitCond(VarF, 0);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
+ assert( RetValue );
+ pLits[0] = toLitCond(VarI, 0);
+ pLits[1] = toLitCond(VarE, 0^fCompE);
+ pLits[2] = toLitCond(VarF, 1);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
+ assert( RetValue );
+
+ // two additional clauses
+ // t' & e' -> f'
+ // t & e -> f
+
+ // t + e + f'
+ // t' + e' + f
+
+ if ( VarT == VarE )
+ {
+// assert( fCompT == !fCompE );
+ return;
+ }
+
+ pLits[0] = toLitCond(VarT, 0^fCompT);
+ pLits[1] = toLitCond(VarE, 0^fCompE);
+ pLits[2] = toLitCond(VarF, 1);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Aig_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
+ assert( RetValue );
+ pLits[0] = toLitCond(VarT, 1^fCompT);
+ pLits[1] = toLitCond(VarE, 1^fCompE);
+ pLits[2] = toLitCond(VarF, 0);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Aig_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
+ assert( RetValue );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Addes clauses to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_AddClausesSuper( Ssw_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper )
+{
+ Aig_Obj_t * pFanin;
+ int * pLits, nLits, RetValue, i;
+ assert( !Aig_IsComplement(pNode) );
+ assert( Aig_ObjIsNode( pNode ) );
+ // create storage for literals
+ nLits = Vec_PtrSize(vSuper) + 1;
+ pLits = ALLOC( int, nLits );
+ // suppose AND-gate is A & B = C
+ // add !A => !C or A + !C
+ Vec_PtrForEachEntry( vSuper, pFanin, i )
+ {
+ pLits[0] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), Aig_IsComplement(pFanin));
+ pLits[1] = toLitCond(Ssw_ObjSatNum(p,pNode), 1);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Aig_Regular(pFanin)->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( pNode->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
+ assert( RetValue );
+ }
+ // add A & B => C or !A + !B + C
+ Vec_PtrForEachEntry( vSuper, pFanin, i )
+ {
+ pLits[i] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), !Aig_IsComplement(pFanin));
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Aig_Regular(pFanin)->fPhase ) pLits[i] = lit_neg( pLits[i] );
+ }
+ }
+ pLits[nLits-1] = toLitCond(Ssw_ObjSatNum(p,pNode), 0);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNode->fPhase ) pLits[nLits-1] = lit_neg( pLits[nLits-1] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + nLits );
+ assert( RetValue );
+ free( pLits );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_CollectSuper_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes )
+{
+ // if the new node is complemented or a PI, another gate begins
+ if ( Aig_IsComplement(pObj) || Aig_ObjIsPi(pObj) ||
+ (!fFirst && Aig_ObjRefs(pObj) > 1) ||
+ (fUseMuxes && Aig_ObjIsMuxType(pObj)) )
+ {
+ Vec_PtrPushUnique( vSuper, pObj );
+ return;
+ }
+ // go through the branches
+ Ssw_CollectSuper_rec( Aig_ObjChild0(pObj), vSuper, 0, fUseMuxes );
+ Ssw_CollectSuper_rec( Aig_ObjChild1(pObj), vSuper, 0, fUseMuxes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects the supergate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_CollectSuper( Aig_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper )
+{
+ assert( !Aig_IsComplement(pObj) );
+ assert( !Aig_ObjIsPi(pObj) );
+ Vec_PtrClear( vSuper );
+ Ssw_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the solver clause database.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ObjAddToFrontier( Ssw_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vFrontier )
+{
+ assert( !Aig_IsComplement(pObj) );
+ if ( Ssw_ObjSatNum(p,pObj) )
+ return;
+ assert( Ssw_ObjSatNum(p,pObj) == 0 );
+ if ( Aig_ObjIsConst1(pObj) )
+ return;
+ if ( p->pPars->fLatchCorrOpt )
+ {
+ Vec_PtrPush( p->vUsedNodes, pObj );
+ if ( Aig_ObjIsPi(pObj) )
+ Vec_PtrPush( p->vUsedPis, pObj );
+ }
+ Ssw_ObjSetSatNum( p, pObj, p->nSatVars++ );
+ sat_solver_setnvars( p->pSat, 100 * (1 + p->nSatVars / 100) );
+ if ( Aig_ObjIsNode(pObj) )
+ Vec_PtrPush( vFrontier, pObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Updates the solver clause database.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_CnfNodeAddToSolver( Ssw_Man_t * p, Aig_Obj_t * pObj )
+{
+ Vec_Ptr_t * vFrontier;
+ Aig_Obj_t * pNode, * pFanin;
+ int i, k, fUseMuxes = 1;
+ // quit if CNF is ready
+ if ( Ssw_ObjSatNum(p,pObj) )
+ return;
+ // start the frontier
+ vFrontier = Vec_PtrAlloc( 100 );
+ Ssw_ObjAddToFrontier( p, pObj, vFrontier );
+ // explore nodes in the frontier
+ Vec_PtrForEachEntry( vFrontier, pNode, i )
+ {
+ // create the supergate
+ assert( Ssw_ObjSatNum(p,pNode) );
+ if ( fUseMuxes && Aig_ObjIsMuxType(pNode) )
+ {
+ Vec_PtrClear( p->vFanins );
+ Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin0( Aig_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin0( Aig_ObjFanin1(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin1(pNode) ) );
+ Vec_PtrForEachEntry( p->vFanins, pFanin, k )
+ Ssw_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier );
+ Ssw_AddClausesMux( p, pNode );
+ }
+ else
+ {
+ Ssw_CollectSuper( pNode, fUseMuxes, p->vFanins );
+ Vec_PtrForEachEntry( p->vFanins, pFanin, k )
+ Ssw_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier );
+ Ssw_AddClausesSuper( p, pNode, p->vFanins );
+ }
+ assert( Vec_PtrSize(p->vFanins) > 1 );
+ }
+ Vec_PtrFree( vFrontier );
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ssw_old/sswCore.c b/src/aig/ssw_old/sswCore.c
new file mode 100644
index 00000000..5b33d96c
--- /dev/null
+++ b/src/aig/ssw_old/sswCore.c
@@ -0,0 +1,293 @@
+/**CFile****************************************************************
+
+ FileName [sswCore.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [The core procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswCore.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManSetDefaultParams( Ssw_Pars_t * p )
+{
+ memset( p, 0, sizeof(Ssw_Pars_t) );
+ p->nPartSize = 0; // size of the partition
+ p->nOverSize = 0; // size of the overlap between partitions
+ p->nFramesK = 1; // the induction depth
+ p->nFramesAddSim = 0; // additional frames to simulate
+ p->nConstrs = 0; // treat the last nConstrs POs as seq constraints
+ p->nBTLimit = 1000; // conflict limit at a node
+ p->nMinDomSize = 100; // min clock domain considered for optimization
+ p->fPolarFlip = 0; // uses polarity adjustment
+ p->fSkipCheck = 0; // do not run equivalence check for unaffected cones
+ p->fLatchCorr = 0; // performs register correspondence
+ p->fSemiFormal = 0; // enable semiformal filtering
+ p->fUniqueness = 0; // enable uniqueness constraints
+ p->fVerbose = 0; // verbose stats
+ // latch correspondence
+ p->fLatchCorrOpt = 0; // performs optimized register correspondence
+ p->nSatVarMax = 1000; // the max number of SAT variables
+ p->nRecycleCalls = 50; // calls to perform before recycling SAT solver
+ // return values
+ p->nIters = 0; // the number of iterations performed
+}
+
+/**Function*************************************************************
+
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManSetDefaultParamsLcorr( Ssw_Pars_t * p )
+{
+ Ssw_ManSetDefaultParams( p );
+ p->fLatchCorrOpt = 1;
+ p->nBTLimit = 10000;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs computation of signal correspondence with constraints.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p )
+{
+ int nSatProof, nSatCallsSat, nRecycles, nSatFailsReal;
+ Aig_Man_t * pAigNew;
+ int RetValue, nIter;
+ int clk, clkTotal = clock();
+ // get the starting stats
+ p->nLitsBeg = Ssw_ClassesLitNum( p->ppClasses );
+ p->nNodesBeg = Aig_ManNodeNum(p->pAig);
+ p->nRegsBeg = Aig_ManRegNum(p->pAig);
+ // refine classes using BMC
+ if ( p->pPars->fVerbose )
+ {
+ printf( "Before BMC: " );
+ Ssw_ClassesPrint( p->ppClasses, 0 );
+ }
+ if ( !p->pPars->fLatchCorr )
+ {
+ Ssw_ManSweepBmc( p );
+ Ssw_ManCleanup( p );
+ }
+ if ( p->pPars->fVerbose )
+ {
+ printf( "After BMC: " );
+ Ssw_ClassesPrint( p->ppClasses, 0 );
+ }
+ // apply semi-formal filtering
+ if ( p->pPars->fSemiFormal )
+ {
+ Aig_Man_t * pSRed;
+ Ssw_FilterUsingBmc( p, 0, 2000, p->pPars->fVerbose );
+// Ssw_FilterUsingBmc( p, 1, 100000, p->pPars->fVerbose );
+ pSRed = Ssw_SpeculativeReduction( p );
+ Aig_ManDumpBlif( pSRed, "srm.blif", NULL, NULL );
+ Aig_ManStop( pSRed );
+ }
+ // refine classes using induction
+ nSatProof = nSatCallsSat = nRecycles = nSatFailsReal = 0;
+ for ( nIter = 0; ; nIter++ )
+ {
+clk = clock();
+ if ( p->pPars->fLatchCorrOpt )
+ {
+ RetValue = Ssw_ManSweepLatch( p );
+ if ( p->pPars->fVerbose )
+ {
+ printf( "%3d : Const = %6d. Cl = %6d. Pr = %5d. Cex = %5d. Rcl = %3d. F = %3d. ",
+ nIter, Ssw_ClassesCand1Num(p->ppClasses), Ssw_ClassesClassNum(p->ppClasses),
+ p->nSatProof-nSatProof, p->nSatCallsSat-nSatCallsSat,
+ p->nRecycles-nRecycles, p->nSatFailsReal-nSatFailsReal );
+ PRT( "T", clock() - clk );
+ nSatProof = p->nSatProof;
+ nSatCallsSat = p->nSatCallsSat;
+ nRecycles = p->nRecycles;
+ nSatFailsReal = p->nSatFailsReal;
+ }
+ }
+ else
+ {
+// if ( nIter == 6 )
+// p->pPars->fUniqueness = 0;
+
+ RetValue = Ssw_ManSweep( p );
+ if ( p->pPars->fVerbose )
+ {
+ printf( "%3d : Const = %6d. Cl = %6d. LR = %6d. NR = %6d. U = %3d. F = %2d. ",
+ nIter, Ssw_ClassesCand1Num(p->ppClasses), Ssw_ClassesClassNum(p->ppClasses),
+ p->nConstrReduced, Aig_ManNodeNum(p->pFrames), p->nUniques, p->nSatFailsReal );
+ if ( p->pPars->fSkipCheck )
+ printf( "Use = %5d. Skip = %5d. ",
+ p->nRefUse, p->nRefSkip );
+ PRT( "T", clock() - clk );
+ }
+ }
+ Ssw_ManCleanup( p );
+ if ( !RetValue )
+ break;
+/*
+ {
+ static int Flag = 0;
+ if ( Flag++ == 4 && nIter == 4 )
+ {
+ Aig_Man_t * pSRed;
+ pSRed = Ssw_SpeculativeReduction( p );
+ Aig_ManDumpBlif( pSRed, "srm.blif", NULL, NULL );
+ Aig_ManStop( pSRed );
+ }
+ }
+*/
+
+ }
+ p->pPars->nIters = nIter + 1;
+p->timeTotal = clock() - clkTotal;
+ pAigNew = Aig_ManDupRepr( p->pAig, 0 );
+ Aig_ManSeqCleanup( pAigNew );
+ // get the final stats
+ p->nLitsEnd = Ssw_ClassesLitNum( p->ppClasses );
+ p->nNodesEnd = Aig_ManNodeNum(pAigNew);
+ p->nRegsEnd = Aig_ManRegNum(pAigNew);
+ return pAigNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs computation of signal correspondence with constraints.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
+{
+ Ssw_Pars_t Pars;
+ Aig_Man_t * pAigNew;
+ Ssw_Man_t * p;
+ assert( Aig_ManRegNum(pAig) > 0 );
+ // reset random numbers
+ Aig_ManRandom( 1 );
+ // if parameters are not given, create them
+ if ( pPars == NULL )
+ Ssw_ManSetDefaultParams( pPars = &Pars );
+ // consider the case of empty AIG
+ if ( Aig_ManNodeNum(pAig) == 0 )
+ {
+ pPars->nIters = 0;
+ // Ntl_ManFinalize() needs the following to satisfy an assertion
+ Aig_ManReprStart( pAig,Aig_ManObjNumMax(pAig) );
+ return Aig_ManDupOrdered(pAig);
+ }
+ // check and update parameters
+ if ( pPars->fLatchCorrOpt )
+ {
+ pPars->fLatchCorr = 1;
+ pPars->nFramesAddSim = 0;
+ }
+ else
+ {
+ assert( pPars->nFramesK > 0 );
+ if ( pPars->nFramesK > 1 )
+ pPars->fSkipCheck = 0;
+ // perform partitioning
+ if ( (pPars->nPartSize > 0 && pPars->nPartSize < Aig_ManRegNum(pAig))
+ || (pAig->vClockDoms && Vec_VecSize(pAig->vClockDoms) > 0) )
+ return Ssw_SignalCorrespondencePart( pAig, pPars );
+ }
+ // start the induction manager
+ p = Ssw_ManCreate( pAig, pPars );
+ // compute candidate equivalence classes
+// p->pPars->nConstrs = 1;
+ if ( p->pPars->nConstrs == 0 )
+ {
+ // perform one round of seq simulation and generate candidate equivalence classes
+ p->ppClasses = Ssw_ClassesPrepare( pAig, pPars->fLatchCorr, pPars->nMaxLevs, pPars->fVerbose );
+// p->ppClasses = Ssw_ClassesPrepareTargets( pAig );
+// p->pSml = Ssw_SmlStart( pAig, 0, p->nFrames + p->pPars->nFramesAddSim, 1 );
+ p->pSml = Ssw_SmlStart( pAig, 0, 1, 1 );
+ Ssw_ClassesSetData( p->ppClasses, p->pSml, Ssw_SmlObjHashWord, Ssw_SmlObjIsConstWord, Ssw_SmlObjsAreEqualWord );
+ }
+ else
+ {
+ // create trivial equivalence classes with all nodes being candidates for constant 1
+ p->ppClasses = Ssw_ClassesPrepareSimple( pAig, pPars->fLatchCorr, pPars->nMaxLevs );
+ Ssw_ClassesSetData( p->ppClasses, NULL, NULL, Ssw_SmlObjIsConstBit, Ssw_SmlObjsAreEqualBit );
+ }
+ // perform refinement of classes
+ pAigNew = Ssw_SignalCorrespondenceRefine( p );
+ // cleanup
+ Ssw_ManStop( p );
+ return pAigNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs computation of latch correspondence.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
+{
+ Ssw_Pars_t Pars;
+ if ( pPars == NULL )
+ Ssw_ManSetDefaultParamsLcorr( pPars = &Pars );
+ return Ssw_SignalCorrespondence( pAig, pPars );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ssw_old/sswInt.h b/src/aig/ssw_old/sswInt.h
new file mode 100644
index 00000000..d7bf46a8
--- /dev/null
+++ b/src/aig/ssw_old/sswInt.h
@@ -0,0 +1,232 @@
+/**CFile****************************************************************
+
+ FileName [sswInt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswInt.h,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __SSW_INT_H__
+#define __SSW_INT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "saig.h"
+#include "satSolver.h"
+#include "ssw.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Ssw_Man_t_ Ssw_Man_t; // signal correspondence manager
+typedef struct Ssw_Cla_t_ Ssw_Cla_t; // equivalence classe manager
+typedef struct Ssw_Sml_t_ Ssw_Sml_t; // sequential simulation manager
+
+struct Ssw_Man_t_
+{
+ // parameters
+ Ssw_Pars_t * pPars; // parameters
+ int nFrames; // for quick lookup
+ // AIGs used in the package
+ Aig_Man_t * pAig; // user-given AIG
+ Aig_Man_t * pFrames; // final AIG
+ Aig_Obj_t ** pNodeToFrames; // mapping of AIG nodes into FRAIG nodes
+ // equivalence classes
+ Ssw_Cla_t * ppClasses; // equivalence classes of nodes
+ int fRefined; // is set to 1 when refinement happens
+ int nRefUse; // the number of equivalences used
+ int nRefSkip; // the number of equivalences skipped
+ // SAT solving
+ sat_solver * pSat; // recyclable SAT solver
+ int nSatVars; // the counter of SAT variables
+ Vec_Int_t * vSatVars; // mapping of each node into its SAT var
+ int nSatVarsTotal; // the total number of SAT vars created
+ Vec_Ptr_t * vFanins; // fanins of the CNF node
+ // SAT solving (latch corr only)
+ Vec_Ptr_t * vUsedNodes; // the nodes with SAT variables
+ Vec_Ptr_t * vUsedPis; // the PIs with SAT variables
+ Vec_Ptr_t * vSimInfo; // simulation information for the framed PIs
+ int nPatterns; // the number of patterns saved
+ int nSimRounds; // the number of simulation rounds performed
+ int nCallsCount; // the number of calls in this round
+ int nCallsDelta; // the number of calls to skip
+ int nCallsSat; // the number of SAT calls in this round
+ int nCallsUnsat; // the number of UNSAT calls in this round
+ int nRecycleCalls; // the number of calls since last recycling
+ int nRecycles; // the number of time SAT solver was recycled
+ int nConeMax; // the maximum cone size
+ // uniqueness
+ Vec_Ptr_t * vCommon; // the set of common variables in the logic cones
+ int iOutputLit; // the output literal of the uniqueness constaint
+ int nUniques; // the number of uniqueness constaints used
+ // sequential simulator
+ Ssw_Sml_t * pSml;
+ // counter example storage
+ int nPatWords; // the number of words in the counter example
+ unsigned * pPatWords; // the counter example
+ unsigned * pPatWords2; // the counter example
+ // constraints
+ int nConstrTotal; // the number of total constraints
+ int nConstrReduced; // the number of reduced constraints
+ int nStrangers; // the number of strange situations
+ // SAT calls statistics
+ int nSatCalls; // the number of SAT calls
+ int nSatProof; // the number of proofs
+ int nSatFailsReal; // the number of timeouts
+ int nSatFailsTotal; // the number of timeouts
+ int nSatCallsUnsat; // the number of unsat SAT calls
+ int nSatCallsSat; // the number of sat SAT calls
+ // node/register/lit statistics
+ int nLitsBeg;
+ int nLitsEnd;
+ int nNodesBeg;
+ int nNodesEnd;
+ int nRegsBeg;
+ int nRegsEnd;
+ // runtime stats
+ int timeBmc; // bounded model checking
+ int timeReduce; // speculative reduction
+ int timeMarkCones; // marking the cones not to be refined
+ int timeSimSat; // simulation of the counter-examples
+ int timeSat; // solving SAT
+ int timeSatSat; // sat
+ int timeSatUnsat; // unsat
+ int timeSatUndec; // undecided
+ int timeOther; // other runtime
+ int timeTotal; // total runtime
+};
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+static inline int Ssw_ObjSatNum( Ssw_Man_t * p, Aig_Obj_t * pObj ) { return Vec_IntEntry( p->vSatVars, pObj->Id ); }
+static inline void Ssw_ObjSetSatNum( Ssw_Man_t * p, Aig_Obj_t * pObj, int Num ) { Vec_IntWriteEntryFill( p->vSatVars, pObj->Id, Num ); }
+
+static inline int Ssw_ObjIsConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj )
+{
+ return Aig_ObjRepr(pAig, pObj) == Aig_ManConst1(pAig);
+}
+static inline void Ssw_ObjSetConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj )
+{
+ assert( !Ssw_ObjIsConst1Cand( pAig, pObj ) );
+ Aig_ObjSetRepr( pAig, pObj, Aig_ManConst1(pAig) );
+}
+
+static inline Aig_Obj_t * Ssw_ObjFrame( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { return p->pNodeToFrames[p->nFrames*pObj->Id + i]; }
+static inline void Ssw_ObjSetFrame( Ssw_Man_t * p, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { p->pNodeToFrames[p->nFrames*pObj->Id + i] = pNode; }
+
+static inline Aig_Obj_t * Ssw_ObjChild0Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)) : NULL; }
+static inline Aig_Obj_t * Ssw_ObjChild1Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)) : NULL; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== sswAig.c ===================================================*/
+extern Aig_Man_t * Ssw_FramesWithClasses( Ssw_Man_t * p );
+extern Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p );
+/*=== sswBmc.c ===================================================*/
+extern int Ssw_FilterUsingBmc( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int fVerbose );
+/*=== sswClass.c =================================================*/
+extern Ssw_Cla_t * Ssw_ClassesStart( Aig_Man_t * pAig );
+extern void Ssw_ClassesSetData( Ssw_Cla_t * p, void * pManData,
+ unsigned (*pFuncNodeHash)(void *,Aig_Obj_t *),
+ int (*pFuncNodeIsConst)(void *,Aig_Obj_t *),
+ int (*pFuncNodesAreEqual)(void *,Aig_Obj_t *, Aig_Obj_t *) );
+extern void Ssw_ClassesStop( Ssw_Cla_t * p );
+extern Aig_Man_t * Ssw_ClassesReadAig( Ssw_Cla_t * p );
+extern Vec_Ptr_t * Ssw_ClassesGetRefined( Ssw_Cla_t * p );
+extern void Ssw_ClassesClearRefined( Ssw_Cla_t * p );
+extern int Ssw_ClassesCand1Num( Ssw_Cla_t * p );
+extern int Ssw_ClassesClassNum( Ssw_Cla_t * p );
+extern int Ssw_ClassesLitNum( Ssw_Cla_t * p );
+extern Aig_Obj_t ** Ssw_ClassesReadClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, int * pnSize );
+extern void Ssw_ClassesCollectClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, Vec_Ptr_t * vClass );
+extern void Ssw_ClassesCheck( Ssw_Cla_t * p );
+extern void Ssw_ClassesPrint( Ssw_Cla_t * p, int fVeryVerbose );
+extern void Ssw_ClassesRemoveNode( Ssw_Cla_t * p, Aig_Obj_t * pObj );
+extern Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs, int fVerbose );
+extern Ssw_Cla_t * Ssw_ClassesPrepareSimple( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs );
+extern Ssw_Cla_t * Ssw_ClassesPrepareTargets( Aig_Man_t * pAig );
+extern Ssw_Cla_t * Ssw_ClassesPreparePairs( Aig_Man_t * pAig, Vec_Int_t ** pvClasses );
+extern int Ssw_ClassesRefine( Ssw_Cla_t * p, int fRecursive );
+extern int Ssw_ClassesRefineOneClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, int fRecursive );
+extern int Ssw_ClassesRefineConst1Group( Ssw_Cla_t * p, Vec_Ptr_t * vRoots, int fRecursive );
+extern int Ssw_ClassesRefineConst1( Ssw_Cla_t * p, int fRecursive );
+/*=== sswCnf.c ===================================================*/
+extern void Ssw_CnfNodeAddToSolver( Ssw_Man_t * p, Aig_Obj_t * pObj );
+/*=== sswCore.c ===================================================*/
+extern Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p );
+/*=== sswLcorr.c ==========================================================*/
+extern int Ssw_ManSweepLatch( Ssw_Man_t * p );
+/*=== sswMan.c ===================================================*/
+extern Ssw_Man_t * Ssw_ManCreate( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
+extern void Ssw_ManCleanup( Ssw_Man_t * p );
+extern void Ssw_ManStop( Ssw_Man_t * p );
+extern void Ssw_ManStartSolver( Ssw_Man_t * p );
+/*=== sswSat.c ===================================================*/
+extern int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew );
+extern int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew );
+/*=== sswSim.c ===================================================*/
+extern unsigned Ssw_SmlObjHashWord( Ssw_Sml_t * p, Aig_Obj_t * pObj );
+extern int Ssw_SmlObjIsConstWord( Ssw_Sml_t * p, Aig_Obj_t * pObj );
+extern int Ssw_SmlObjsAreEqualWord( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 );
+extern int Ssw_SmlObjIsConstBit( void * p, Aig_Obj_t * pObj );
+extern int Ssw_SmlObjsAreEqualBit( void * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 );
+extern Ssw_Sml_t * Ssw_SmlStart( Aig_Man_t * pAig, int nPref, int nFrames, int nWordsFrame );
+extern void Ssw_SmlClean( Ssw_Sml_t * p );
+extern void Ssw_SmlStop( Ssw_Sml_t * p );
+extern void Ssw_SmlObjAssignConst( Ssw_Sml_t * p, Aig_Obj_t * pObj, int fConst1, int iFrame );
+extern unsigned Ssw_SmlObjGetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iWord, int iFrame );
+extern void Ssw_SmlObjSetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, unsigned Word, int iWord, int iFrame );
+extern void Ssw_SmlAssignDist1Plus( Ssw_Sml_t * p, unsigned * pPat );
+extern void Ssw_SmlSimulateOne( Ssw_Sml_t * p );
+extern void Ssw_SmlSimulateOneFrame( Ssw_Sml_t * p );
+extern Ssw_Sml_t * Ssw_SmlSimulateSeq( Aig_Man_t * pAig, int nPref, int nFrames, int nWords );
+/*=== sswSimSat.c ===================================================*/
+extern void Ssw_ManResimulateBit( Ssw_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pRepr );
+extern void Ssw_ManResimulateWord( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f );
+extern void Ssw_ManResimulateWord2( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f );
+/*=== sswSweep.c ===================================================*/
+extern int Ssw_ManGetSatVarValue( Ssw_Man_t * p, Aig_Obj_t * pObj, int f );
+extern int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc );
+extern int Ssw_ManSweepBmc( Ssw_Man_t * p );
+extern int Ssw_ManSweep( Ssw_Man_t * p );
+/*=== sswUnique.c ===================================================*/
+extern int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj );
+extern int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int f2 );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/aig/ssw_old/sswLcorr.c b/src/aig/ssw_old/sswLcorr.c
new file mode 100644
index 00000000..cde9b0c9
--- /dev/null
+++ b/src/aig/ssw_old/sswLcorr.c
@@ -0,0 +1,364 @@
+/**CFile****************************************************************
+
+ FileName [sswLcorr.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Latch correspondence.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswLcorr.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+//#include "bar.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Recycles the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManSatSolverRecycle( Ssw_Man_t * p )
+{
+ int Lit;
+ if ( p->pSat )
+ {
+ Aig_Obj_t * pObj;
+ int i;
+ Vec_PtrForEachEntry( p->vUsedNodes, pObj, i )
+ Ssw_ObjSetSatNum( p, pObj, 0 );
+ Vec_PtrClear( p->vUsedNodes );
+ Vec_PtrClear( p->vUsedPis );
+// memset( p->pSatVars, 0, sizeof(int) * Aig_ManObjNumMax(p->pAigTotal) );
+ sat_solver_delete( p->pSat );
+ }
+ p->pSat = sat_solver_new();
+ sat_solver_setnvars( p->pSat, 1000 );
+ // var 0 is not used
+ // var 1 is reserved for const1 node - add the clause
+ p->nSatVars = 1;
+// p->nSatVars = 0;
+ Lit = toLit( p->nSatVars );
+ if ( p->pPars->fPolarFlip )
+ Lit = lit_neg( Lit );
+ sat_solver_addclause( p->pSat, &Lit, &Lit + 1 );
+ Ssw_ObjSetSatNum( p, Aig_ManConst1(p->pFrames), p->nSatVars++ );
+
+ p->nRecycles++;
+ p->nRecycleCalls = 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Tranfers simulation information from FRAIG to AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManSweepTransfer( Ssw_Man_t * p )
+{
+ Aig_Obj_t * pObj, * pObjFraig;
+ unsigned * pInfo;
+ int i;
+ // transfer simulation information
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pObjFraig = Ssw_ObjFrame( p, pObj, 0 );
+ if ( pObjFraig == Aig_ManConst0(p->pFrames) )
+ {
+ Ssw_SmlObjAssignConst( p->pSml, pObj, 0, 0 );
+ continue;
+ }
+ assert( !Aig_IsComplement(pObjFraig) );
+ assert( Aig_ObjIsPi(pObjFraig) );
+ pInfo = Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObjFraig) );
+ Ssw_SmlObjSetWord( p->pSml, pObj, pInfo[0], 0, 0 );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs one round of simulation with counter-examples.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepResimulate( Ssw_Man_t * p )
+{
+ int RetValue1, RetValue2, clk = clock();
+ // transfer PI simulation information from storage
+ Ssw_ManSweepTransfer( p );
+ // simulate internal nodes
+ Ssw_SmlSimulateOneFrame( p->pSml );
+ // check equivalence classes
+ RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 );
+ RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 );
+ // prepare simulation info for the next round
+ Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 );
+ p->nPatterns = 0;
+ p->nSimRounds++;
+p->timeSimSat += clock() - clk;
+ return RetValue1 > 0 || RetValue2 > 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Saves one counter-example into internal storage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlAddPattern( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pCand )
+{
+ Aig_Obj_t * pObj;
+ unsigned * pInfo;
+ int i, nVarNum, Value;
+ Vec_PtrForEachEntry( p->vUsedPis, pObj, i )
+ {
+ nVarNum = Ssw_ObjSatNum( p, pObj );
+ assert( nVarNum > 0 );
+ Value = sat_solver_var_value( p->pSat, nVarNum );
+ if ( Value == 0 )
+ continue;
+ pInfo = Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObj) );
+ Aig_InfoSetBit( pInfo, p->nPatterns );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Builds fraiged logic cone of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManBuildCone_rec( Ssw_Man_t * p, Aig_Obj_t * pObj )
+{
+ Aig_Obj_t * pObjNew;
+ assert( !Aig_IsComplement(pObj) );
+ if ( Ssw_ObjFrame( p, pObj, 0 ) )
+ return;
+ assert( Aig_ObjIsNode(pObj) );
+ Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObj) );
+ Ssw_ManBuildCone_rec( p, Aig_ObjFanin1(pObj) );
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, 0), Ssw_ObjChild1Fra(p, pObj, 0) );
+ Ssw_ObjSetFrame( p, pObj, 0, pObjNew );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recycles the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManSweepLatchOne( Ssw_Man_t * p, Aig_Obj_t * pObjRepr, Aig_Obj_t * pObj )
+{
+ Aig_Obj_t * pObjFraig, * pObjReprFraig, * pObjLi;
+ int RetValue, clk;
+ assert( Aig_ObjIsPi(pObj) );
+ assert( Aig_ObjIsPi(pObjRepr) || Aig_ObjIsConst1(pObjRepr) );
+ // check if it makes sense to skip some calls
+ if ( p->nCallsCount > 100 && p->nCallsUnsat < p->nCallsSat )
+ {
+ if ( ++p->nCallsDelta < 0 )
+ return;
+ }
+ p->nCallsDelta = 0;
+clk = clock();
+ // get the fraiged node
+ pObjLi = Saig_ObjLoToLi( p->pAig, pObj );
+ Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObjLi) );
+ pObjFraig = Ssw_ObjChild0Fra( p, pObjLi, 0 );
+ // get the fraiged representative
+ if ( Aig_ObjIsPi(pObjRepr) )
+ {
+ pObjLi = Saig_ObjLoToLi( p->pAig, pObjRepr );
+ Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObjLi) );
+ pObjReprFraig = Ssw_ObjChild0Fra( p, pObjLi, 0 );
+ }
+ else
+ pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, 0 );
+p->timeReduce += clock() - clk;
+ // if the fraiged nodes are the same, return
+ if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) )
+ return;
+ p->nRecycleCalls++;
+ p->nCallsCount++;
+
+ // check equivalence of the two nodes
+ if ( (pObj->fPhase == pObjRepr->fPhase) != (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) )
+ {
+ p->nPatterns++;
+ p->nStrangers++;
+ p->fRefined = 1;
+ }
+ else
+ {
+ RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
+ if ( RetValue == 1 ) // proved equivalence
+ {
+ p->nCallsUnsat++;
+ return;
+ }
+ if ( RetValue == -1 ) // timed out
+ {
+ Ssw_ClassesRemoveNode( p->ppClasses, pObj );
+ p->nCallsUnsat++;
+ p->fRefined = 1;
+ return;
+ }
+ else // disproved equivalence
+ {
+ Ssw_SmlAddPattern( p, pObjRepr, pObj );
+ p->nPatterns++;
+ p->nCallsSat++;
+ p->fRefined = 1;
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs one iteration of sweeping latches.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepLatch( Ssw_Man_t * p )
+{
+// Bar_Progress_t * pProgress = NULL;
+ Vec_Ptr_t * vClass;
+ Aig_Obj_t * pObj, * pRepr, * pTemp;
+ int i, k;
+
+ // start the timeframe
+ p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) );
+ // map constants and PIs
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), 0, Aig_ManConst1(p->pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(p->pFrames) );
+
+ // implement equivalence classes
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ {
+ pRepr = Aig_ObjRepr( p->pAig, pObj );
+ if ( pRepr == NULL )
+ {
+ pTemp = Aig_ObjCreatePi(p->pFrames);
+ pTemp->pData = pObj;
+ }
+ else
+ pTemp = Aig_NotCond( Ssw_ObjFrame(p, pRepr, 0), pRepr->fPhase ^ pObj->fPhase );
+ Ssw_ObjSetFrame( p, pObj, 0, pTemp );
+ }
+ Aig_ManSetPioNumbers( p->pFrames );
+
+ // prepare simulation info
+ assert( p->vSimInfo == NULL );
+ p->vSimInfo = Vec_PtrAllocSimInfo( Aig_ManPiNum(p->pFrames), 1 );
+ Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 );
+
+ // go through the registers
+// if ( p->pPars->fVerbose )
+// pProgress = Bar_ProgressStart( stdout, Aig_ManRegNum(p->pAig) );
+ vClass = Vec_PtrAlloc( 100 );
+ p->fRefined = 0;
+ p->nCallsCount = p->nCallsSat = p->nCallsUnsat = 0;
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ {
+// if ( p->pPars->fVerbose )
+// Bar_ProgressUpdate( pProgress, i, NULL );
+ // consider the case of constant candidate
+ if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) )
+ Ssw_ManSweepLatchOne( p, Aig_ManConst1(p->pAig), pObj );
+ else
+ {
+ // consider the case of equivalence class
+ Ssw_ClassesCollectClass( p->ppClasses, pObj, vClass );
+ if ( Vec_PtrSize(vClass) == 0 )
+ continue;
+ // try to prove equivalences in this class
+ Vec_PtrForEachEntry( vClass, pTemp, k )
+ if ( Aig_ObjRepr(p->pAig, pTemp) == pObj )
+ {
+ Ssw_ManSweepLatchOne( p, pObj, pTemp );
+ if ( p->nPatterns == 32 )
+ break;
+ }
+ }
+ // resimulate
+ if ( p->nPatterns == 32 )
+ Ssw_ManSweepResimulate( p );
+ // attempt recycling the SAT solver
+ if ( p->pPars->nSatVarMax &&
+ p->nSatVars > p->pPars->nSatVarMax &&
+ p->nRecycleCalls > p->pPars->nRecycleCalls )
+ Ssw_ManSatSolverRecycle( p );
+ }
+ // resimulate
+ if ( p->nPatterns > 0 )
+ Ssw_ManSweepResimulate( p );
+ // cleanup
+ Vec_PtrFree( vClass );
+ p->nSatFailsTotal += p->nSatFailsReal;
+// if ( p->pPars->fVerbose )
+// Bar_ProgressStop( pProgress );
+
+ // cleanup
+// Ssw_ClassesCheck( p->ppClasses );
+ return p->fRefined;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ssw_old/sswMan.c b/src/aig/ssw_old/sswMan.c
new file mode 100644
index 00000000..84b041b4
--- /dev/null
+++ b/src/aig/ssw_old/sswMan.c
@@ -0,0 +1,237 @@
+/**CFile****************************************************************
+
+ FileName [sswMan.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Calls to the SAT solver.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswMan.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Creates the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Man_t * Ssw_ManCreate( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
+{
+ Ssw_Man_t * p;
+ // prepare the sequential AIG
+ assert( Saig_ManRegNum(pAig) > 0 );
+ Aig_ManFanoutStart( pAig );
+ Aig_ManSetPioNumbers( pAig );
+ // create interpolation manager
+ p = ALLOC( Ssw_Man_t, 1 );
+ memset( p, 0, sizeof(Ssw_Man_t) );
+ p->pPars = pPars;
+ p->pAig = pAig;
+ p->nFrames = pPars->nFramesK + 1;
+ p->pNodeToFrames = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pAig) * p->nFrames );
+ // SAT solving
+ p->vSatVars = Vec_IntStart( Aig_ManObjNumMax(p->pAig) * (p->nFrames+1) );
+ p->vFanins = Vec_PtrAlloc( 100 );
+ // SAT solving (latch corr only)
+ p->vUsedNodes = Vec_PtrAlloc( 1000 );
+ p->vUsedPis = Vec_PtrAlloc( 1000 );
+ p->vCommon = Vec_PtrAlloc( 100 );
+ p->iOutputLit = -1;
+ // allocate storage for sim pattern
+ p->nPatWords = Aig_BitWordNum( Saig_ManPiNum(pAig) * p->nFrames + Saig_ManRegNum(pAig) );
+ p->pPatWords = ALLOC( unsigned, p->nPatWords );
+ p->pPatWords2 = ALLOC( unsigned, p->nPatWords );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints stats of the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManCountEquivs( Ssw_Man_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i, nEquivs = 0;
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ nEquivs += ( Aig_ObjRepr(p->pAig, pObj) != NULL );
+ return nEquivs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints stats of the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManPrintStats( Ssw_Man_t * p )
+{
+ double nMemory = 1.0*Aig_ManObjNumMax(p->pAig)*p->nFrames*(2*sizeof(int)+2*sizeof(void*))/(1<<20);
+
+ printf( "Parameters: F = %d. AddF = %d. C-lim = %d. Constr = %d. MaxLev = %d. Mem = %0.2f Mb.\n",
+ p->pPars->nFramesK, p->pPars->nFramesAddSim, p->pPars->nBTLimit, p->pPars->nConstrs, p->pPars->nMaxLevs, nMemory );
+ printf( "AIG : PI = %d. PO = %d. Latch = %d. Node = %d. Ave SAT vars = %d.\n",
+ Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), Saig_ManRegNum(p->pAig), Aig_ManNodeNum(p->pAig),
+ p->nSatVarsTotal/p->pPars->nIters );
+ printf( "SAT calls : Proof = %d. Cex = %d. Fail = %d. Equivs = %d. Str = %d.\n",
+ p->nSatProof, p->nSatCallsSat, p->nSatFailsTotal, Ssw_ManCountEquivs(p), p->nStrangers );
+ printf( "SAT solver: Vars = %d. Max cone = %d. Recycles = %d. Rounds = %d.\n",
+ p->nSatVars, p->nConeMax, p->nRecycles, p->nSimRounds );
+ printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",
+ p->nNodesBeg, p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/(p->nNodesBeg?p->nNodesBeg:1),
+ p->nRegsBeg, p->nRegsEnd, 100.0*(p->nRegsBeg-p->nRegsEnd)/(p->nRegsBeg?p->nRegsBeg:1) );
+
+ p->timeOther = p->timeTotal-p->timeBmc-p->timeReduce-p->timeMarkCones-p->timeSimSat-p->timeSat;
+ PRTP( "BMC ", p->timeBmc, p->timeTotal );
+ PRTP( "Spec reduce", p->timeReduce, p->timeTotal );
+ PRTP( "Mark cones ", p->timeMarkCones, p->timeTotal );
+ PRTP( "Sim SAT ", p->timeSimSat, p->timeTotal );
+ PRTP( "SAT solving", p->timeSat, p->timeTotal );
+ PRTP( " unsat ", p->timeSatUnsat, p->timeTotal );
+ PRTP( " sat ", p->timeSatSat, p->timeTotal );
+ PRTP( " undecided", p->timeSatUndec, p->timeTotal );
+ PRTP( "Other ", p->timeOther, p->timeTotal );
+ PRTP( "TOTAL ", p->timeTotal, p->timeTotal );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManCleanup( Ssw_Man_t * p )
+{
+ if ( p->pFrames )
+ {
+ Aig_ManStop( p->pFrames );
+ p->pFrames = NULL;
+ memset( p->pNodeToFrames, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(p->pAig) * p->nFrames );
+ }
+ if ( p->pSat )
+ {
+ int i;
+// printf( "Vars = %d. Clauses = %d. Learnts = %d.\n", p->pSat->size, p->pSat->clauses.size, p->pSat->learnts.size );
+ p->nSatVarsTotal += p->pSat->size;
+ sat_solver_delete( p->pSat );
+ p->pSat = NULL;
+// memset( p->pSatVars, 0, sizeof(int) * Aig_ManObjNumMax(p->pAig) * (p->nFrames+1) );
+ for ( i = 0; i < Vec_IntSize(p->vSatVars); i++ )
+ p->vSatVars->pArray[i] = 0;
+ }
+ if ( p->vSimInfo )
+ {
+ Vec_PtrFree( p->vSimInfo );
+ p->vSimInfo = NULL;
+ }
+ p->nConstrTotal = 0;
+ p->nConstrReduced = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManStop( Ssw_Man_t * p )
+{
+ Aig_ManCleanMarkA( p->pAig );
+ Aig_ManCleanMarkB( p->pAig );
+ if ( p->pPars->fVerbose )
+ Ssw_ManPrintStats( p );
+ if ( p->ppClasses )
+ Ssw_ClassesStop( p->ppClasses );
+ if ( p->pSml )
+ Ssw_SmlStop( p->pSml );
+ Vec_PtrFree( p->vFanins );
+ Vec_PtrFree( p->vUsedNodes );
+ Vec_PtrFree( p->vUsedPis );
+ Vec_IntFree( p->vSatVars );
+ Vec_PtrFree( p->vCommon );
+ FREE( p->pNodeToFrames );
+ FREE( p->pPatWords );
+ FREE( p->pPatWords2 );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManStartSolver( Ssw_Man_t * p )
+{
+ int Lit;
+ assert( p->pSat == NULL );
+ p->pSat = sat_solver_new();
+ sat_solver_setnvars( p->pSat, 1000 );
+ // var 0 is not used
+ // var 1 is reserved for const1 node - add the clause
+ p->nSatVars = 1;
+ Lit = toLit( p->nSatVars );
+ if ( p->pPars->fPolarFlip )
+ Lit = lit_neg( Lit );
+ sat_solver_addclause( p->pSat, &Lit, &Lit + 1 );
+ Ssw_ObjSetSatNum( p, Aig_ManConst1(p->pAig), p->nSatVars++ );
+
+ Vec_PtrClear( p->vUsedNodes );
+ Vec_PtrClear( p->vUsedPis );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ssw_old/sswPairs.c b/src/aig/ssw_old/sswPairs.c
new file mode 100644
index 00000000..c77ad30d
--- /dev/null
+++ b/src/aig/ssw_old/sswPairs.c
@@ -0,0 +1,470 @@
+/**CFile****************************************************************
+
+ FileName [sswPairs.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Calls to the SAT solver.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswPairs.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Reports the status of the miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_MiterStatus( Aig_Man_t * p, int fVerbose )
+{
+ Aig_Obj_t * pObj, * pChild;
+ int i, CountConst0 = 0, CountNonConst0 = 0, CountUndecided = 0;
+// if ( p->pData )
+// return 0;
+ Saig_ManForEachPo( p, pObj, i )
+ {
+ pChild = Aig_ObjChild0(pObj);
+ // check if the output is constant 0
+ if ( pChild == Aig_ManConst0(p) )
+ {
+ CountConst0++;
+ continue;
+ }
+ // check if the output is constant 1
+ if ( pChild == Aig_ManConst1(p) )
+ {
+ CountNonConst0++;
+ continue;
+ }
+ // check if the output is a primary input
+ if ( p->nRegs == 0 && Aig_ObjIsPi(Aig_Regular(pChild)) )
+ {
+ CountNonConst0++;
+ continue;
+ }
+ // check if the output can be not constant 0
+ if ( Aig_Regular(pChild)->fPhase != (unsigned)Aig_IsComplement(pChild) )
+ {
+ CountNonConst0++;
+ continue;
+ }
+ CountUndecided++;
+ }
+
+ if ( fVerbose )
+ {
+ printf( "Miter has %d outputs. ", Saig_ManPoNum(p) );
+ printf( "Const0 = %d. ", CountConst0 );
+ printf( "NonConst0 = %d. ", CountNonConst0 );
+ printf( "Undecided = %d. ", CountUndecided );
+ printf( "\n" );
+ }
+
+ if ( CountNonConst0 )
+ return 0;
+ if ( CountUndecided )
+ return -1;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transfer equivalent pairs to the miter.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Ssw_TransferSignalPairs( Aig_Man_t * pMiter, Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2 )
+{
+ Vec_Int_t * vIds;
+ Aig_Obj_t * pObj1, * pObj2;
+ Aig_Obj_t * pObj1m, * pObj2m;
+ int i;
+ vIds = Vec_IntAlloc( 2 * Vec_IntSize(vIds1) );
+ for ( i = 0; i < Vec_IntSize(vIds1); i++ )
+ {
+ pObj1 = Aig_ManObj( pAig1, Vec_IntEntry(vIds1, i) );
+ pObj2 = Aig_ManObj( pAig2, Vec_IntEntry(vIds2, i) );
+ pObj1m = Aig_Regular(pObj1->pData);
+ pObj2m = Aig_Regular(pObj2->pData);
+ assert( pObj1m && pObj2m );
+ if ( pObj1m == pObj2m )
+ continue;
+ if ( pObj1m->Id < pObj2m->Id )
+ {
+ Vec_IntPush( vIds, pObj1m->Id );
+ Vec_IntPush( vIds, pObj2m->Id );
+ }
+ else
+ {
+ Vec_IntPush( vIds, pObj2m->Id );
+ Vec_IntPush( vIds, pObj1m->Id );
+ }
+ }
+ return vIds;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transform pairs into class representation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t ** Ssw_TransformPairsIntoTempClasses( Vec_Int_t * vPairs, int nObjNumMax )
+{
+ Vec_Int_t ** pvClasses; // vector of classes
+ int * pReprs; // mapping nodes into their representatives
+ int Entry, idObj, idRepr, idReprObj, idReprRepr, i;
+ // allocate data-structures
+ pvClasses = CALLOC( Vec_Int_t *, nObjNumMax );
+ pReprs = ALLOC( int, nObjNumMax );
+ for ( i = 0; i < nObjNumMax; i++ )
+ pReprs[i] = -1;
+ // consider pairs
+ for ( i = 0; i < Vec_IntSize(vPairs); i += 2 )
+ {
+ // get both objects
+ idRepr = Vec_IntEntry( vPairs, i );
+ idObj = Vec_IntEntry( vPairs, i+1 );
+ assert( idObj > 0 );
+ assert( (pReprs[idRepr] == -1) || (pvClasses[pReprs[idRepr]] != NULL) );
+ assert( (pReprs[idObj] == -1) || (pvClasses[pReprs[idObj] ] != NULL) );
+ // get representatives of both objects
+ idReprRepr = pReprs[idRepr];
+ idReprObj = pReprs[idObj];
+ // check different situations
+ if ( idReprRepr == -1 && idReprObj == -1 )
+ { // they do not have classes
+ // create a class
+ pvClasses[idRepr] = Vec_IntAlloc( 4 );
+ Vec_IntPush( pvClasses[idRepr], idRepr );
+ Vec_IntPush( pvClasses[idRepr], idObj );
+ pReprs[ idRepr ] = idRepr;
+ pReprs[ idObj ] = idRepr;
+ }
+ else if ( idReprRepr >= 0 && idReprObj == -1 )
+ { // representative has a class
+ // add iObj to the same class
+ Vec_IntPushUniqueOrder( pvClasses[idReprRepr], idObj );
+ pReprs[ idObj ] = idReprRepr;
+ }
+ else if ( idReprRepr == -1 && idReprObj >= 0 )
+ { // object has a class
+ assert( idReprObj != idRepr );
+ if ( idReprObj < idRepr )
+ { // add idRepr to the same class
+ Vec_IntPushUniqueOrder( pvClasses[idReprObj], idRepr );
+ pReprs[ idRepr ] = idReprObj;
+ }
+ else // if ( idReprObj > idRepr )
+ { // make idRepr new representative
+ Vec_IntPushFirst( pvClasses[idReprObj], idRepr );
+ pvClasses[idRepr] = pvClasses[idReprObj];
+ pvClasses[idReprObj] = NULL;
+ // set correct representatives of each node
+ Vec_IntForEachEntry( pvClasses[idRepr], Entry, i )
+ pReprs[ Entry ] = idRepr;
+ }
+ }
+ else // if ( idReprRepr >= 0 && idReprObj >= 0 )
+ { // both have classes
+ if ( idReprRepr == idReprObj )
+ { // the classes are the same
+ // nothing to do
+ }
+ else
+ { // the classes are different
+ // find the repr of the new class
+ if ( idReprRepr < idReprObj )
+ {
+ Vec_IntForEachEntry( pvClasses[idReprObj], Entry, i )
+ {
+ Vec_IntPushUniqueOrder( pvClasses[idReprRepr], Entry );
+ pReprs[ Entry ] = idReprRepr;
+ }
+ Vec_IntFree( pvClasses[idReprObj] );
+ pvClasses[idReprObj] = NULL;
+ }
+ else // if ( idReprRepr > idReprObj )
+ {
+ Vec_IntForEachEntry( pvClasses[idReprRepr], Entry, i )
+ {
+ Vec_IntPushUniqueOrder( pvClasses[idReprObj], Entry );
+ pReprs[ Entry ] = idReprObj;
+ }
+ Vec_IntFree( pvClasses[idReprRepr] );
+ pvClasses[idReprRepr] = NULL;
+ }
+ }
+ }
+ }
+ free( pReprs );
+ return pvClasses;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_FreeTempClasses( Vec_Int_t ** pvClasses, int nObjNumMax )
+{
+ int i;
+ for ( i = 0; i < nObjNumMax; i++ )
+ if ( pvClasses[i] )
+ Vec_IntFree( pvClasses[i] );
+ free( pvClasses );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs signal correspondence for the miter of two AIGs with node pairs defined.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_SignalCorrespondenceWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2, Ssw_Pars_t * pPars )
+{
+ Ssw_Man_t * p;
+ Aig_Man_t * pAigNew, * pMiter;
+ Ssw_Pars_t Pars;
+ Vec_Int_t * vPairs;
+ Vec_Int_t ** pvClasses;
+ assert( Vec_IntSize(vIds1) == Vec_IntSize(vIds2) );
+ // create sequential miter
+ pMiter = Saig_ManCreateMiter( pAig1, pAig2, 0 );
+ // transfer information to the miter
+ vPairs = Ssw_TransferSignalPairs( pMiter, pAig1, pAig2, vIds1, vIds2 );
+ // create representation of the classes
+ pvClasses = Ssw_TransformPairsIntoTempClasses( vPairs, Aig_ManObjNumMax(pMiter) );
+ Vec_IntFree( vPairs );
+ // if parameters are not given, create them
+ if ( pPars == NULL )
+ Ssw_ManSetDefaultParams( pPars = &Pars );
+ // start the induction manager
+ p = Ssw_ManCreate( pMiter, pPars );
+ // create equivalence classes using these IDs
+ p->ppClasses = Ssw_ClassesPreparePairs( pMiter, pvClasses );
+ p->pSml = Ssw_SmlStart( pMiter, 0, p->nFrames + p->pPars->nFramesAddSim, 1 );
+ Ssw_ClassesSetData( p->ppClasses, p->pSml, Ssw_SmlObjHashWord, Ssw_SmlObjIsConstWord, Ssw_SmlObjsAreEqualWord );
+ // perform refinement of classes
+ pAigNew = Ssw_SignalCorrespondenceRefine( p );
+ // cleanup
+ Ssw_FreeTempClasses( pvClasses, Aig_ManObjNumMax(pMiter) );
+ Ssw_ManStop( p );
+ Aig_ManStop( pMiter );
+ return pAigNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Runs inductive SEC for the miter of two AIGs with node pairs defined.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_SignalCorrespondeceTestPairs( Aig_Man_t * pAig )
+{
+ Aig_Man_t * pAigNew, * pAigRes;
+ Ssw_Pars_t Pars, * pPars = &Pars;
+ Vec_Int_t * vIds1, * vIds2;
+ Aig_Obj_t * pObj, * pRepr;
+ int RetValue, i, clk = clock();
+ Ssw_ManSetDefaultParams( pPars );
+ pPars->fVerbose = 1;
+ pAigNew = Ssw_SignalCorrespondence( pAig, pPars );
+ // record pairs of equivalent nodes
+ vIds1 = Vec_IntAlloc( Aig_ManObjNumMax(pAig) );
+ vIds2 = Vec_IntAlloc( Aig_ManObjNumMax(pAig) );
+ Aig_ManForEachObj( pAig, pObj, i )
+ {
+ pRepr = Aig_Regular(pObj->pData);
+ if ( pRepr == NULL )
+ continue;
+ if ( Aig_ManObj(pAigNew, pRepr->Id) == NULL )
+ continue;
+/*
+ if ( Aig_ObjIsNode(pObj) )
+ printf( "n " );
+ else if ( Saig_ObjIsPi(pAig, pObj) )
+ printf( "pi " );
+ else if ( Saig_ObjIsLo(pAig, pObj) )
+ printf( "lo " );
+*/
+ Vec_IntPush( vIds1, Aig_ObjId(pObj) );
+ Vec_IntPush( vIds2, Aig_ObjId(pRepr) );
+ }
+ printf( "Recorded %d pairs (before: %d after: %d).\n", Vec_IntSize(vIds1), Aig_ManObjNumMax(pAig), Aig_ManObjNumMax(pAigNew) );
+ // try the new AIGs
+ pAigRes = Ssw_SignalCorrespondenceWithPairs( pAig, pAigNew, vIds1, vIds2, pPars );
+ Vec_IntFree( vIds1 );
+ Vec_IntFree( vIds2 );
+ // report the results
+ RetValue = Ssw_MiterStatus( pAigRes, 1 );
+ if ( RetValue == 1 )
+ printf( "Verification successful. " );
+ else if ( RetValue == 0 )
+ printf( "Verification failed with the counter-example. " );
+ else
+ printf( "Verification UNDECIDED. Remaining registers %d (total %d). ",
+ Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig) + Aig_ManRegNum(pAigNew) );
+ PRT( "Time", clock() - clk );
+ // cleanup
+ Aig_ManStop( pAigNew );
+ return pAigRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Runs inductive SEC for the miter of two AIGs with node pairs defined.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SecWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2, Ssw_Pars_t * pPars )
+{
+ Aig_Man_t * pAigRes;
+ int RetValue, clk = clock();
+ assert( vIds1 != NULL && vIds2 != NULL );
+ // try the new AIGs
+ printf( "Performing specialized verification with node pairs.\n" );
+ pAigRes = Ssw_SignalCorrespondenceWithPairs( pAig1, pAig2, vIds1, vIds2, pPars );
+ // report the results
+ RetValue = Ssw_MiterStatus( pAigRes, 1 );
+ if ( RetValue == 1 )
+ printf( "Verification successful. " );
+ else if ( RetValue == 0 )
+ printf( "Verification failed with a counter-example. " );
+ else
+ printf( "Verification UNDECIDED. The number of remaining regs = %d (total = %d). ",
+ Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig1) + Aig_ManRegNum(pAig2) );
+ PRT( "Time", clock() - clk );
+ // cleanup
+ Aig_ManStop( pAigRes );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Runs inductive SEC for the miter of two AIGs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SecGeneral( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Ssw_Pars_t * pPars )
+{
+ Aig_Man_t * pAigRes, * pMiter;
+ int RetValue, clk = clock();
+ // try the new AIGs
+ printf( "Performing general verification without node pairs.\n" );
+ pMiter = Saig_ManCreateMiter( pAig1, pAig2, 0 );
+ pAigRes = Ssw_SignalCorrespondence( pMiter, pPars );
+ Aig_ManStop( pMiter );
+ // report the results
+ RetValue = Ssw_MiterStatus( pAigRes, 1 );
+ if ( RetValue == 1 )
+ printf( "Verification successful. " );
+ else if ( RetValue == 0 )
+ printf( "Verification failed with a counter-example. " );
+ else
+ printf( "Verification UNDECIDED. The number of remaining regs = %d (total = %d). ",
+ Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig1) + Aig_ManRegNum(pAig2) );
+ PRT( "Time", clock() - clk );
+ // cleanup
+ Aig_ManStop( pAigRes );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Runs inductive SEC for the miter of two AIGs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SecGeneralMiter( Aig_Man_t * pMiter, Ssw_Pars_t * pPars )
+{
+ Aig_Man_t * pAigRes;
+ int RetValue, clk = clock();
+ // try the new AIGs
+// printf( "Performing general verification without node pairs.\n" );
+ pAigRes = Ssw_SignalCorrespondence( pMiter, pPars );
+ // report the results
+ RetValue = Ssw_MiterStatus( pAigRes, 1 );
+ if ( RetValue == 1 )
+ printf( "Verification successful. " );
+ else if ( RetValue == 0 )
+ printf( "Verification failed with a counter-example. " );
+ else
+ printf( "Verification UNDECIDED. The number of remaining regs = %d (total = %d). ",
+ Aig_ManRegNum(pAigRes), Aig_ManRegNum(pMiter) );
+ PRT( "Time", clock() - clk );
+ // cleanup
+ Aig_ManStop( pAigRes );
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ssw_old/sswPart.c b/src/aig/ssw_old/sswPart.c
new file mode 100644
index 00000000..7eb6b8fe
--- /dev/null
+++ b/src/aig/ssw_old/sswPart.c
@@ -0,0 +1,129 @@
+/**CFile****************************************************************
+
+ FileName [sswPart.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Partitioned signal correspondence.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswPart.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Performs partitioned sequential SAT sweepingG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
+{
+ int fPrintParts = 0;
+ char Buffer[100];
+ Aig_Man_t * pTemp, * pNew;
+ Vec_Ptr_t * vResult;
+ Vec_Int_t * vPart;
+ int * pMapBack;
+ int i, nCountPis, nCountRegs;
+ int nClasses, nPartSize, fVerbose;
+ int clk = clock();
+
+ // save parameters
+ nPartSize = pPars->nPartSize; pPars->nPartSize = 0;
+ fVerbose = pPars->fVerbose; pPars->fVerbose = 0;
+ // generate partitions
+ if ( pAig->vClockDoms )
+ {
+ // divide large clock domains into separate partitions
+ vResult = Vec_PtrAlloc( 100 );
+ Vec_PtrForEachEntry( (Vec_Ptr_t *)pAig->vClockDoms, vPart, i )
+ {
+ if ( nPartSize && Vec_IntSize(vPart) > nPartSize )
+ Aig_ManPartDivide( vResult, vPart, nPartSize, pPars->nOverSize );
+ else
+ Vec_PtrPush( vResult, Vec_IntDup(vPart) );
+ }
+ }
+ else
+ vResult = Aig_ManRegPartitionSimple( pAig, nPartSize, pPars->nOverSize );
+// vResult = Aig_ManPartitionSmartRegisters( pAig, nPartSize, 0 );
+// vResult = Aig_ManRegPartitionSmart( pAig, nPartSize );
+ if ( fPrintParts )
+ {
+ // print partitions
+ printf( "Simple partitioning. %d partitions are saved:\n", Vec_PtrSize(vResult) );
+ Vec_PtrForEachEntry( vResult, vPart, i )
+ {
+ extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact );
+ sprintf( Buffer, "part%03d.aig", i );
+ pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, NULL );
+ Ioa_WriteAiger( pTemp, Buffer, 0, 0 );
+ printf( "part%03d.aig : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d.\n",
+ i, Vec_IntSize(vPart), Aig_ManPiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp) );
+ Aig_ManStop( pTemp );
+ }
+ }
+
+ // perform SSW with partitions
+ Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) );
+ Vec_PtrForEachEntry( vResult, vPart, i )
+ {
+ pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, &pMapBack );
+ Aig_ManSetRegNum( pTemp, pTemp->nRegs );
+ // create the projection of 1-hot registers
+ if ( pAig->vOnehots )
+ pTemp->vOnehots = Aig_ManRegProjectOnehots( pAig, pTemp, pAig->vOnehots, fVerbose );
+ // run SSW
+ pNew = Ssw_SignalCorrespondence( pTemp, pPars );
+ nClasses = Aig_TransferMappedClasses( pAig, pTemp, pMapBack );
+ if ( fVerbose )
+ printf( "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. It = %3d. Cl = %5d.\n",
+ i, Vec_IntSize(vPart), Aig_ManPiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp), pPars->nIters, nClasses );
+ Aig_ManStop( pNew );
+ Aig_ManStop( pTemp );
+ free( pMapBack );
+ }
+ // remap the AIG
+ pNew = Aig_ManDupRepr( pAig, 0 );
+ Aig_ManSeqCleanup( pNew );
+// Aig_ManPrintStats( pAig );
+// Aig_ManPrintStats( pNew );
+ Vec_VecFree( (Vec_Vec_t *)vResult );
+ pPars->nPartSize = nPartSize;
+ pPars->fVerbose = fVerbose;
+ if ( fVerbose )
+ {
+ PRT( "Total time", clock() - clk );
+ }
+ return pNew;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ssw_old/sswSat.c b/src/aig/ssw_old/sswSat.c
new file mode 100644
index 00000000..85d3b8c1
--- /dev/null
+++ b/src/aig/ssw_old/sswSat.c
@@ -0,0 +1,264 @@
+/**CFile****************************************************************
+
+ FileName [sswSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Calls to the SAT solver.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswSat.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Runs equivalence test for the two nodes.]
+
+ Description [Both nodes should be regular and different from each other.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
+{
+ int nBTLimit = p->pPars->nBTLimit;
+ int pLits[3], nLits, RetValue, RetValue1, clk;//, status;
+ p->nSatCalls++;
+
+ // sanity checks
+ assert( !Aig_IsComplement(pOld) );
+ assert( !Aig_IsComplement(pNew) );
+ assert( pOld != pNew );
+
+ if ( p->pSat == NULL )
+ Ssw_ManStartSolver( p );
+
+ // if the nodes do not have SAT variables, allocate them
+ Ssw_CnfNodeAddToSolver( p, pOld );
+ Ssw_CnfNodeAddToSolver( p, pNew );
+
+ if ( p->pSat->qtail != p->pSat->qhead )
+ {
+ RetValue = sat_solver_simplify(p->pSat);
+ assert( RetValue != 0 );
+ }
+
+ // solve under assumptions
+ // A = 1; B = 0 OR A = 1; B = 1
+ nLits = 2;
+ pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 0 );
+ pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), pOld->fPhase == pNew->fPhase );
+ if ( p->iOutputLit > -1 )
+ pLits[nLits++] = p->iOutputLit;
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ }
+//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 );
+
+clk = clock();
+ RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + nLits,
+ (sint64)nBTLimit, (sint64)0, (sint64)0, (sint64)0 );
+p->timeSat += clock() - clk;
+ if ( RetValue1 == l_False )
+ {
+p->timeSatUnsat += clock() - clk;
+ if ( nLits == 2 )
+ {
+ pLits[0] = lit_neg( pLits[0] );
+ pLits[1] = lit_neg( pLits[1] );
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
+ assert( RetValue );
+ }
+ p->nSatCallsUnsat++;
+ }
+ else if ( RetValue1 == l_True )
+ {
+p->timeSatSat += clock() - clk;
+ p->nSatCallsSat++;
+ return 0;
+ }
+ else // if ( RetValue1 == l_Undef )
+ {
+p->timeSatUndec += clock() - clk;
+ p->nSatFailsReal++;
+ return -1;
+ }
+
+ // if the old node was constant 0, we already know the answer
+ if ( pOld == Aig_ManConst1(p->pFrames) )
+ {
+ p->nSatProof++;
+ return 1;
+ }
+
+ // solve under assumptions
+ // A = 0; B = 1 OR A = 0; B = 0
+ nLits = 2;
+ pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 1 );
+ pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), pOld->fPhase ^ pNew->fPhase );
+ if ( p->iOutputLit > -1 )
+ pLits[nLits++] = p->iOutputLit;
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ }
+/*
+ if ( p->pSat->qtail != p->pSat->qhead )
+ {
+ RetValue = sat_solver_simplify(p->pSat);
+ assert( RetValue != 0 );
+ }
+*/
+clk = clock();
+ RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + nLits,
+ (sint64)nBTLimit, (sint64)0, (sint64)0, (sint64)0 );
+p->timeSat += clock() - clk;
+ if ( RetValue1 == l_False )
+ {
+p->timeSatUnsat += clock() - clk;
+ if ( nLits == 2 )
+ {
+ pLits[0] = lit_neg( pLits[0] );
+ pLits[1] = lit_neg( pLits[1] );
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
+ assert( RetValue );
+ }
+ p->nSatCallsUnsat++;
+ }
+ else if ( RetValue1 == l_True )
+ {
+p->timeSatSat += clock() - clk;
+ p->nSatCallsSat++;
+ return 0;
+ }
+ else // if ( RetValue1 == l_Undef )
+ {
+p->timeSatUndec += clock() - clk;
+ p->nSatFailsReal++;
+ return -1;
+ }
+ // return SAT proof
+ p->nSatProof++;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Constrains two nodes to be equivalent in the SAT solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
+{
+ int pLits[2], RetValue, fComplNew;
+ Aig_Obj_t * pTemp;
+
+ // sanity checks
+ assert( Aig_Regular(pOld) != Aig_Regular(pNew) );
+
+ // move constant to the old node
+ if ( Aig_Regular(pNew) == Aig_ManConst1(p->pFrames) )
+ {
+ assert( Aig_Regular(pOld) != Aig_ManConst1(p->pFrames) );
+ pTemp = pOld;
+ pOld = pNew;
+ pNew = pTemp;
+ }
+
+ // move complement to the new node
+ if ( Aig_IsComplement(pOld) )
+ {
+ pOld = Aig_Regular(pOld);
+ pNew = Aig_Not(pNew);
+ }
+
+ // start the solver
+ if ( p->pSat == NULL )
+ Ssw_ManStartSolver( p );
+
+ // if the nodes do not have SAT variables, allocate them
+ Ssw_CnfNodeAddToSolver( p, pOld );
+ Ssw_CnfNodeAddToSolver( p, Aig_Regular(pNew) );
+
+ // transform the new node
+ fComplNew = Aig_IsComplement( pNew );
+ pNew = Aig_Regular( pNew );
+
+ // consider the constant 1 case
+ if ( pOld == Aig_ManConst1(p->pFrames) )
+ {
+ // add constaint A = 1 ----> A
+ pLits[0] = toLitCond( Ssw_ObjSatNum(p,pNew), fComplNew );
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pNew->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ }
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 1 );
+ assert( RetValue );
+ }
+ else
+ {
+ // add constaint A = B ----> (A v !B)(!A v B)
+
+ // (A v !B)
+ pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 0 );
+ pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), !fComplNew );
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ }
+ pLits[0] = lit_neg( pLits[0] );
+ pLits[1] = lit_neg( pLits[1] );
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
+ assert( RetValue );
+
+ // (!A v B)
+ pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 1 );
+ pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), fComplNew);
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
+ if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
+ }
+ pLits[0] = lit_neg( pLits[0] );
+ pLits[1] = lit_neg( pLits[1] );
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
+ assert( RetValue );
+ }
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ssw_old/sswSim.c b/src/aig/ssw_old/sswSim.c
new file mode 100644
index 00000000..3fdb5cbc
--- /dev/null
+++ b/src/aig/ssw_old/sswSim.c
@@ -0,0 +1,1334 @@
+/**CFile****************************************************************
+
+ FileName [sswSim.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Sequential simulator used by the inductive prover.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswSim.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// simulation manager
+struct Ssw_Sml_t_
+{
+ Aig_Man_t * pAig; // the original AIG manager
+ int nPref; // the number of timeframes in the prefix
+ int nFrames; // the number of timeframes
+ int nWordsFrame; // the number of words in each timeframe
+ int nWordsTotal; // the total number of words at a node
+ int nWordsPref; // the number of word in the prefix
+ int fNonConstOut; // have seen a non-const-0 output during simulation
+ int nSimRounds; // statistics
+ int timeSim; // statistics
+ unsigned pData[0]; // simulation data for the nodes
+};
+
+static inline unsigned * Ssw_ObjSim( Ssw_Sml_t * p, int Id ) { return p->pData + p->nWordsTotal * Id; }
+static inline unsigned Ssw_ObjRandomSim() { return Aig_ManRandom(0); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Computes hash value of the node using its simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Ssw_SmlObjHashWord( Ssw_Sml_t * p, Aig_Obj_t * pObj )
+{
+ static int s_SPrimes[128] = {
+ 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459,
+ 1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997,
+ 2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543,
+ 2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089,
+ 3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671,
+ 3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243,
+ 4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871,
+ 4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471,
+ 5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073,
+ 6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689,
+ 6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309,
+ 7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933,
+ 8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147
+ };
+ unsigned * pSims;
+ unsigned uHash;
+ int i;
+ assert( p->nWordsTotal <= 128 );
+ uHash = 0;
+ pSims = Ssw_ObjSim(p, pObj->Id);
+ for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
+ uHash ^= pSims[i] * s_SPrimes[i & 0x7F];
+ return uHash;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if simulation info is composed of all zeros.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlObjIsConstWord( Ssw_Sml_t * p, Aig_Obj_t * pObj )
+{
+ unsigned * pSims;
+ int i;
+ pSims = Ssw_ObjSim(p, pObj->Id);
+ for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
+ if ( pSims[i] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if simulation infos are equal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlObjsAreEqualWord( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
+{
+ unsigned * pSims0, * pSims1;
+ int i;
+ pSims0 = Ssw_ObjSim(p, pObj0->Id);
+ pSims1 = Ssw_ObjSim(p, pObj1->Id);
+ for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
+ if ( pSims0[i] != pSims1[i] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the node appears to be constant 1 candidate.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlObjIsConstBit( void * p, Aig_Obj_t * pObj )
+{
+ return pObj->fPhase == pObj->fMarkB;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the nodes appear equal.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlObjsAreEqualBit( void * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
+{
+ return (pObj0->fPhase == pObj1->fPhase) == (pObj0->fMarkB == pObj1->fMarkB);
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of 1s in the XOR of simulation data.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlNodeNotEquWeight( Ssw_Sml_t * p, int Left, int Right )
+{
+ unsigned * pSimL, * pSimR;
+ int k, Counter = 0;
+ pSimL = Ssw_ObjSim( p, Left );
+ pSimR = Ssw_ObjSim( p, Right );
+ for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
+ Counter += Aig_WordCountOnes( pSimL[k] ^ pSimR[k] );
+ return Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if simulation info is composed of all zeros.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlNodeIsZero( Ssw_Sml_t * p, Aig_Obj_t * pObj )
+{
+ unsigned * pSims;
+ int i;
+ pSims = Ssw_ObjSim(p, pObj->Id);
+ for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
+ if ( pSims[i] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Counts the number of one's in the patten of the output.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlNodeCountOnes( Ssw_Sml_t * p, Aig_Obj_t * pObj )
+{
+ unsigned * pSims;
+ int i, Counter = 0;
+ pSims = Ssw_ObjSim(p, pObj->Id);
+ for ( i = 0; i < p->nWordsTotal; i++ )
+ Counter += Aig_WordCountOnes( pSims[i] );
+ return Counter;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Generated const 0 pattern.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSavePattern0( Ssw_Man_t * p, int fInit )
+{
+ memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
+}
+
+/**Function*************************************************************
+
+ Synopsis [[Generated const 1 pattern.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSavePattern1( Ssw_Man_t * p, int fInit )
+{
+ Aig_Obj_t * pObj;
+ int i, k, nTruePis;
+ memset( p->pPatWords, 0xff, sizeof(unsigned) * p->nPatWords );
+ if ( !fInit )
+ return;
+ // clear the state bits to correspond to all-0 initial state
+ nTruePis = Saig_ManPiNum(p->pAig);
+ k = 0;
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Aig_InfoXorBit( p->pPatWords, nTruePis * p->nFrames + k++ );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Copy pattern from the solver into the internal storage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSavePattern( Ssw_Man_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
+ Aig_ManForEachPi( p->pFrames, pObj, i )
+ if ( p->pSat->model.ptr[Ssw_ObjSatNum(p, pObj)] == l_True )
+ Aig_InfoSetBit( p->pPatWords, i );
+/*
+ if ( p->vCex )
+ {
+ Vec_IntClear( p->vCex );
+ for ( i = 0; i < Saig_ManPiNum(p->pAig); i++ )
+ Vec_IntPush( p->vCex, Aig_InfoHasBit( p->pPatWords, i ) );
+ for ( i = Saig_ManPiNum(p->pFrames); i < Aig_ManPiNum(p->pFrames); i++ )
+ Vec_IntPush( p->vCex, Aig_InfoHasBit( p->pPatWords, i ) );
+ }
+*/
+
+/*
+ printf( "Pattern: " );
+ Aig_ManForEachPi( p->pFrames, pObj, i )
+ printf( "%d", Aig_InfoHasBit( p->pPatWords, i ) );
+ printf( "\n" );
+*/
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Creates the counter-example from the successful pattern.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Ssw_SmlCheckOutputSavePattern( Ssw_Sml_t * p, Aig_Obj_t * pObjPo )
+{
+ Aig_Obj_t * pFanin, * pObjPi;
+ unsigned * pSims;
+ int i, k, BestPat, * pModel;
+ // find the word of the pattern
+ pFanin = Aig_ObjFanin0(pObjPo);
+ pSims = Ssw_ObjSim(p, pFanin->Id);
+ for ( i = 0; i < p->nWordsTotal; i++ )
+ if ( pSims[i] )
+ break;
+ assert( i < p->nWordsTotal );
+ // find the bit of the pattern
+ for ( k = 0; k < 32; k++ )
+ if ( pSims[i] & (1 << k) )
+ break;
+ assert( k < 32 );
+ // determine the best pattern
+ BestPat = i * 32 + k;
+ // fill in the counter-example data
+ pModel = ALLOC( int, Aig_ManPiNum(p->pAig)+1 );
+ Aig_ManForEachPi( p->pAig, pObjPi, i )
+ {
+ pModel[i] = Aig_InfoHasBit(Ssw_ObjSim(p, pObjPi->Id), BestPat);
+// printf( "%d", pModel[i] );
+ }
+ pModel[Aig_ManPiNum(p->pAig)] = pObjPo->Id;
+// printf( "\n" );
+ return pModel;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if the one of the output is already non-constant 0.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Ssw_SmlCheckOutput( Ssw_Sml_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ // make sure the reference simulation pattern does not detect the bug
+ pObj = Aig_ManPo( p->pAig, 0 );
+ assert( Aig_ObjFanin0(pObj)->fPhase == (unsigned)Aig_ObjFaninC0(pObj) );
+ Aig_ManForEachPo( p->pAig, pObj, i )
+ {
+ if ( !Ssw_SmlObjIsConstWord( p, Aig_ObjFanin0(pObj) ) )
+ {
+ // create the counter-example from this pattern
+ return Ssw_SmlCheckOutputSavePattern( p, pObj );
+ }
+ }
+ return NULL;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Assigns random patterns to the PI node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlAssignRandom( Ssw_Sml_t * p, Aig_Obj_t * pObj )
+{
+ unsigned * pSims;
+ int i;
+ assert( Aig_ObjIsPi(pObj) );
+ pSims = Ssw_ObjSim( p, pObj->Id );
+ for ( i = 0; i < p->nWordsTotal; i++ )
+ pSims[i] = Ssw_ObjRandomSim();
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assigns random patterns to the PI node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlAssignRandomFrame( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iFrame )
+{
+ unsigned * pSims;
+ int i;
+ assert( Aig_ObjIsPi(pObj) );
+ pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = Ssw_ObjRandomSim();
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assigns constant patterns to the PI node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlObjAssignConst( Ssw_Sml_t * p, Aig_Obj_t * pObj, int fConst1, int iFrame )
+{
+ unsigned * pSims;
+ int i;
+ assert( Aig_ObjIsPi(pObj) );
+ pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = fConst1? ~(unsigned)0 : 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assigns constant patterns to the PI node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Ssw_SmlObjGetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iWord, int iFrame )
+{
+ unsigned * pSims;
+// assert( Aig_ObjIsPi(pObj) );
+ pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
+ return pSims[iWord];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assigns constant patterns to the PI node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlObjSetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, unsigned Word, int iWord, int iFrame )
+{
+ unsigned * pSims;
+ assert( Aig_ObjIsPi(pObj) );
+ pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
+ pSims[iWord] = Word;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assings random simulation info for the PIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlInitialize( Ssw_Sml_t * p, int fInit )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ if ( fInit )
+ {
+ assert( Aig_ManRegNum(p->pAig) > 0 );
+ assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) );
+ // assign random info for primary inputs
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlAssignRandom( p, pObj );
+ // assign the initial state for the latches
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_SmlObjAssignConst( p, pObj, 0, 0 );
+ }
+ else
+ {
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlAssignRandom( p, pObj );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assings distance-1 simulation info for the PIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlAssignDist1( Ssw_Sml_t * p, unsigned * pPat )
+{
+ Aig_Obj_t * pObj;
+ int f, i, k, Limit, nTruePis;
+ assert( p->nFrames > 0 );
+ if ( p->nFrames == 1 )
+ {
+ // copy the PI info
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlObjAssignConst( p, pObj, Aig_InfoHasBit(pPat, i), 0 );
+ // flip one bit
+ Limit = AIG_MIN( Aig_ManPiNum(p->pAig), p->nWordsTotal * 32 - 1 );
+ for ( i = 0; i < Limit; i++ )
+ Aig_InfoXorBit( Ssw_ObjSim( p, Aig_ManPi(p->pAig,i)->Id ), i+1 );
+ }
+ else
+ {
+ int fUseDist1 = 0;
+
+ // copy the PI info for each frame
+ nTruePis = Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig);
+ for ( f = 0; f < p->nFrames; f++ )
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlObjAssignConst( p, pObj, Aig_InfoHasBit(pPat, nTruePis * f + i), f );
+ // copy the latch info
+ k = 0;
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_SmlObjAssignConst( p, pObj, Aig_InfoHasBit(pPat, nTruePis * p->nFrames + k++), 0 );
+// assert( p->pFrames == NULL || nTruePis * p->nFrames + k == Aig_ManPiNum(p->pFrames) );
+
+ // flip one bit of the last frame
+ if ( fUseDist1 ) //&& p->nFrames == 2 )
+ {
+ Limit = AIG_MIN( nTruePis, p->nWordsFrame * 32 - 1 );
+ for ( i = 0; i < Limit; i++ )
+ Aig_InfoXorBit( Ssw_ObjSim( p, Aig_ManPi(p->pAig, i)->Id ) + p->nWordsFrame*(p->nFrames-1), i+1 );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Assings distance-1 simulation info for the PIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlAssignDist1Plus( Ssw_Sml_t * p, unsigned * pPat )
+{
+ Aig_Obj_t * pObj;
+ int f, i, Limit;
+ assert( p->nFrames > 0 );
+
+ // copy the pattern into the primary inputs
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlObjAssignConst( p, pObj, Aig_InfoHasBit(pPat, i), 0 );
+/*
+ // set distance one PIs for the first frame
+ Limit = AIG_MIN( Saig_ManPiNum(p->pAig), p->nWordsFrame * 32 - 1 );
+ for ( i = 0; i < Limit; i++ )
+ Aig_InfoXorBit( Ssw_ObjSim( p, Aig_ManPi(p->pAig, i)->Id ), i+1 );
+*/
+ // create random info for the remaining timeframes
+ for ( f = 1; f < p->nFrames; f++ )
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_SmlAssignRandomFrame( p, pObj, f );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlNodeSimulate( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iFrame )
+{
+ unsigned * pSims, * pSims0, * pSims1;
+ int fCompl, fCompl0, fCompl1, i;
+ assert( !Aig_IsComplement(pObj) );
+ assert( Aig_ObjIsNode(pObj) );
+ assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal );
+ // get hold of the simulation information
+ pSims = Ssw_ObjSim(p, pObj->Id) + p->nWordsFrame * iFrame;
+ pSims0 = Ssw_ObjSim(p, Aig_ObjFanin0(pObj)->Id) + p->nWordsFrame * iFrame;
+ pSims1 = Ssw_ObjSim(p, Aig_ObjFanin1(pObj)->Id) + p->nWordsFrame * iFrame;
+ // get complemented attributes of the children using their random info
+ fCompl = pObj->fPhase;
+ fCompl0 = Aig_ObjPhaseReal(Aig_ObjChild0(pObj));
+ fCompl1 = Aig_ObjPhaseReal(Aig_ObjChild1(pObj));
+ // simulate
+ if ( fCompl0 && fCompl1 )
+ {
+ if ( fCompl )
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = (pSims0[i] | pSims1[i]);
+ else
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = ~(pSims0[i] | pSims1[i]);
+ }
+ else if ( fCompl0 && !fCompl1 )
+ {
+ if ( fCompl )
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = (pSims0[i] | ~pSims1[i]);
+ else
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = (~pSims0[i] & pSims1[i]);
+ }
+ else if ( !fCompl0 && fCompl1 )
+ {
+ if ( fCompl )
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = (~pSims0[i] | pSims1[i]);
+ else
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = (pSims0[i] & ~pSims1[i]);
+ }
+ else // if ( !fCompl0 && !fCompl1 )
+ {
+ if ( fCompl )
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = ~(pSims0[i] & pSims1[i]);
+ else
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = (pSims0[i] & pSims1[i]);
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlNodesCompareInFrame( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1, int iFrame0, int iFrame1 )
+{
+ unsigned * pSims0, * pSims1;
+ int i;
+ assert( !Aig_IsComplement(pObj0) );
+ assert( !Aig_IsComplement(pObj1) );
+ assert( iFrame0 == 0 || p->nWordsFrame < p->nWordsTotal );
+ assert( iFrame1 == 0 || p->nWordsFrame < p->nWordsTotal );
+ // get hold of the simulation information
+ pSims0 = Ssw_ObjSim(p, pObj0->Id) + p->nWordsFrame * iFrame0;
+ pSims1 = Ssw_ObjSim(p, pObj1->Id) + p->nWordsFrame * iFrame1;
+ // compare
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ if ( pSims0[i] != pSims1[i] )
+ return 0;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlNodeCopyFanin( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iFrame )
+{
+ unsigned * pSims, * pSims0;
+ int fCompl, fCompl0, i;
+ assert( !Aig_IsComplement(pObj) );
+ assert( Aig_ObjIsPo(pObj) );
+ assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal );
+ // get hold of the simulation information
+ pSims = Ssw_ObjSim(p, pObj->Id) + p->nWordsFrame * iFrame;
+ pSims0 = Ssw_ObjSim(p, Aig_ObjFanin0(pObj)->Id) + p->nWordsFrame * iFrame;
+ // get complemented attributes of the children using their random info
+ fCompl = pObj->fPhase;
+ fCompl0 = Aig_ObjPhaseReal(Aig_ObjChild0(pObj));
+ // copy information as it is
+ if ( fCompl0 )
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = ~pSims0[i];
+ else
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims[i] = pSims0[i];
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates one node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlNodeTransferNext( Ssw_Sml_t * p, Aig_Obj_t * pOut, Aig_Obj_t * pIn, int iFrame )
+{
+ unsigned * pSims0, * pSims1;
+ int i;
+ assert( !Aig_IsComplement(pOut) );
+ assert( !Aig_IsComplement(pIn) );
+ assert( Aig_ObjIsPo(pOut) );
+ assert( Aig_ObjIsPi(pIn) );
+ assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal );
+ // get hold of the simulation information
+ pSims0 = Ssw_ObjSim(p, pOut->Id) + p->nWordsFrame * iFrame;
+ pSims1 = Ssw_ObjSim(p, pIn->Id) + p->nWordsFrame * (iFrame+1);
+ // copy information as it is
+ for ( i = 0; i < p->nWordsFrame; i++ )
+ pSims1[i] = pSims0[i];
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Check if any of the POs becomes non-constant.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlCheckNonConstOutputs( Ssw_Sml_t * p )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ Saig_ManForEachPo( p->pAig, pObj, i )
+ if ( !Ssw_SmlNodeIsZero(p, pObj) )
+ return 1;
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates AIG manager.]
+
+ Description [Assumes that the PI simulation info is attached.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSimulateOne( Ssw_Sml_t * p )
+{
+ Aig_Obj_t * pObj, * pObjLi, * pObjLo;
+ int f, i, clk;
+clk = clock();
+ for ( f = 0; f < p->nFrames; f++ )
+ {
+ // simulate the nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ Ssw_SmlNodeSimulate( p, pObj, f );
+ // copy simulation info into outputs
+ Saig_ManForEachPo( p->pAig, pObj, i )
+ Ssw_SmlNodeCopyFanin( p, pObj, f );
+ // quit if this is the last timeframe
+ if ( f == p->nFrames - 1 )
+ break;
+ // copy simulation info into outputs
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ Ssw_SmlNodeCopyFanin( p, pObj, f );
+ // copy simulation info into the inputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ Ssw_SmlNodeTransferNext( p, pObjLi, pObjLo, f );
+ }
+p->timeSim += clock() - clk;
+p->nSimRounds++;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Simulates AIG manager.]
+
+ Description [Assumes that the PI simulation info is attached.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSimulateOneFrame( Ssw_Sml_t * p )
+{
+ Aig_Obj_t * pObj, * pObjLi, * pObjLo;
+ int i, clk;
+clk = clock();
+ // simulate the nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ Ssw_SmlNodeSimulate( p, pObj, 0 );
+ // copy simulation info into outputs
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ Ssw_SmlNodeCopyFanin( p, pObj, 0 );
+ // copy simulation info into the inputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ Ssw_SmlNodeTransferNext( p, pObjLi, pObjLo, 0 );
+p->timeSim += clock() - clk;
+p->nSimRounds++;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Allocates simulation manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Sml_t * Ssw_SmlStart( Aig_Man_t * pAig, int nPref, int nFrames, int nWordsFrame )
+{
+ Ssw_Sml_t * p;
+ p = (Ssw_Sml_t *)malloc( sizeof(Ssw_Sml_t) + sizeof(unsigned) * Aig_ManObjNumMax(pAig) * (nPref + nFrames) * nWordsFrame );
+ memset( p, 0, sizeof(Ssw_Sml_t) + sizeof(unsigned) * (nPref + nFrames) * nWordsFrame );
+ p->pAig = pAig;
+ p->nPref = nPref;
+ p->nFrames = nPref + nFrames;
+ p->nWordsFrame = nWordsFrame;
+ p->nWordsTotal = (nPref + nFrames) * nWordsFrame;
+ p->nWordsPref = nPref * nWordsFrame;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates simulation manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlClean( Ssw_Sml_t * p )
+{
+ memset( p->pData, 0, sizeof(unsigned) * Aig_ManObjNumMax(p->pAig) * p->nWordsTotal );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deallocates simulation manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlStop( Ssw_Sml_t * p )
+{
+ free( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Performs simulation of the uninitialized circuit.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Sml_t * Ssw_SmlSimulateComb( Aig_Man_t * pAig, int nWords )
+{
+ Ssw_Sml_t * p;
+ p = Ssw_SmlStart( pAig, 0, 1, nWords );
+ Ssw_SmlInitialize( p, 0 );
+ Ssw_SmlSimulateOne( p );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs simulation of the initialized circuit.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Sml_t * Ssw_SmlSimulateSeq( Aig_Man_t * pAig, int nPref, int nFrames, int nWords )
+{
+ Ssw_Sml_t * p;
+ p = Ssw_SmlStart( pAig, nPref, nFrames, nWords );
+ Ssw_SmlInitialize( p, 1 );
+ Ssw_SmlSimulateOne( p );
+ p->fNonConstOut = Ssw_SmlCheckNonConstOutputs( p );
+ return p;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Allocates a counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames )
+{
+ Ssw_Cex_t * pCex;
+ int nWords = Aig_BitWordNum( nRegs + nRealPis * nFrames );
+ pCex = (Ssw_Cex_t *)malloc( sizeof(Ssw_Cex_t) + sizeof(unsigned) * nWords );
+ memset( pCex, 0, sizeof(Ssw_Cex_t) + sizeof(unsigned) * nWords );
+ pCex->nRegs = nRegs;
+ pCex->nPis = nRealPis;
+ pCex->nBits = nRegs + nRealPis * nFrames;
+ return pCex;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlFreeCounterExample( Ssw_Cex_t * pCex )
+{
+ free( pCex );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resimulates the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p )
+{
+ Ssw_Sml_t * pSml;
+ Aig_Obj_t * pObj;
+ int RetValue, i, k, iBit;
+ assert( Aig_ManRegNum(pAig) > 0 );
+ assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) );
+ // start a new sequential simulator
+ pSml = Ssw_SmlStart( pAig, 0, p->iFrame+1, 1 );
+ // assign simulation info for the registers
+ iBit = 0;
+ Saig_ManForEachLo( pAig, pObj, i )
+ Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 );
+ // assign simulation info for the primary inputs
+ for ( i = 0; i <= p->iFrame; i++ )
+ Saig_ManForEachPi( pAig, pObj, k )
+ Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i );
+ assert( iBit == p->nBits );
+ // run random simulation
+ Ssw_SmlSimulateOne( pSml );
+ // check if the given output has failed
+ RetValue = !Ssw_SmlNodeIsZero( pSml, Aig_ManPo(pAig, p->iPo) );
+ Ssw_SmlStop( pSml );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resimulates the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p )
+{
+ Ssw_Sml_t * pSml;
+ Aig_Obj_t * pObj;
+ int i, k, iBit, iOut;
+ assert( Aig_ManRegNum(pAig) > 0 );
+ assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) );
+ // start a new sequential simulator
+ pSml = Ssw_SmlStart( pAig, 0, p->iFrame+1, 1 );
+ // assign simulation info for the registers
+ iBit = 0;
+ Saig_ManForEachLo( pAig, pObj, i )
+ Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 );
+ // assign simulation info for the primary inputs
+ for ( i = 0; i <= p->iFrame; i++ )
+ Saig_ManForEachPi( pAig, pObj, k )
+ Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i );
+ assert( iBit == p->nBits );
+ // run random simulation
+ Ssw_SmlSimulateOne( pSml );
+ // check if the given output has failed
+ iOut = -1;
+ Saig_ManForEachPo( pAig, pObj, k )
+ if ( !Ssw_SmlNodeIsZero( pSml, Aig_ManPo(pAig, k) ) )
+ {
+ iOut = k;
+ break;
+ }
+ Ssw_SmlStop( pSml );
+ return iOut;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates sequential counter-example from the simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cex_t * Ssw_SmlGetCounterExample( Ssw_Sml_t * p )
+{
+ Ssw_Cex_t * pCex;
+ Aig_Obj_t * pObj;
+ unsigned * pSims;
+ int iPo, iFrame, iBit, i, k;
+
+ // make sure the simulation manager has it
+ assert( p->fNonConstOut );
+
+ // find the first output that failed
+ iPo = -1;
+ iBit = -1;
+ iFrame = -1;
+ Saig_ManForEachPo( p->pAig, pObj, iPo )
+ {
+ if ( Ssw_SmlNodeIsZero(p, pObj) )
+ continue;
+ pSims = Ssw_ObjSim( p, pObj->Id );
+ for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
+ if ( pSims[i] )
+ {
+ iFrame = i / p->nWordsFrame;
+ iBit = 32 * (i % p->nWordsFrame) + Aig_WordFindFirstBit( pSims[i] );
+ break;
+ }
+ break;
+ }
+ assert( iPo < Aig_ManPoNum(p->pAig)-Aig_ManRegNum(p->pAig) );
+ assert( iFrame < p->nFrames );
+ assert( iBit < 32 * p->nWordsFrame );
+
+ // allocate the counter example
+ pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p->pAig), Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig), iFrame + 1 );
+ pCex->iPo = iPo;
+ pCex->iFrame = iFrame;
+
+ // copy the bit data
+ Saig_ManForEachLo( p->pAig, pObj, k )
+ {
+ pSims = Ssw_ObjSim( p, pObj->Id );
+ if ( Aig_InfoHasBit( pSims, iBit ) )
+ Aig_InfoSetBit( pCex->pData, k );
+ }
+ for ( i = 0; i <= iFrame; i++ )
+ {
+ Saig_ManForEachPi( p->pAig, pObj, k )
+ {
+ pSims = Ssw_ObjSim( p, pObj->Id );
+ if ( Aig_InfoHasBit( pSims, 32 * p->nWordsFrame * i + iBit ) )
+ Aig_InfoSetBit( pCex->pData, pCex->nRegs + pCex->nPis * i + k );
+ }
+ }
+ // verify the counter example
+ if ( !Ssw_SmlRunCounterExample( p->pAig, pCex ) )
+ {
+ printf( "Ssw_SmlGetCounterExample(): Counter-example is invalid.\n" );
+ Ssw_SmlFreeCounterExample( pCex );
+ pCex = NULL;
+ }
+ return pCex;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Generates seq counter-example from the combinational one.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cex_t * Ssw_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel )
+{
+ Ssw_Cex_t * pCex;
+ Aig_Obj_t * pObj;
+ int i, nFrames, nTruePis, nTruePos, iPo, iFrame;
+ // get the number of frames
+ assert( Aig_ManRegNum(pAig) > 0 );
+ assert( Aig_ManRegNum(pFrames) == 0 );
+ nTruePis = Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig);
+ nTruePos = Aig_ManPoNum(pAig)-Aig_ManRegNum(pAig);
+ nFrames = Aig_ManPiNum(pFrames) / nTruePis;
+ assert( nTruePis * nFrames == Aig_ManPiNum(pFrames) );
+ assert( nTruePos * nFrames == Aig_ManPoNum(pFrames) );
+ // find the PO that failed
+ iPo = -1;
+ iFrame = -1;
+ Aig_ManForEachPo( pFrames, pObj, i )
+ if ( pObj->Id == pModel[Aig_ManPiNum(pFrames)] )
+ {
+ iPo = i % nTruePos;
+ iFrame = i / nTruePos;
+ break;
+ }
+ assert( iPo >= 0 );
+ // allocate the counter example
+ pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), nTruePis, iFrame + 1 );
+ pCex->iPo = iPo;
+ pCex->iFrame = iFrame;
+
+ // copy the bit data
+ for ( i = 0; i < Aig_ManPiNum(pFrames); i++ )
+ {
+ if ( pModel[i] )
+ Aig_InfoSetBit( pCex->pData, pCex->nRegs + i );
+ if ( pCex->nRegs + i == pCex->nBits - 1 )
+ break;
+ }
+
+ // verify the counter example
+ if ( !Ssw_SmlRunCounterExample( pAig, pCex ) )
+ {
+ printf( "Ssw_SmlGetCounterExample(): Counter-example is invalid.\n" );
+ Ssw_SmlFreeCounterExample( pCex );
+ pCex = NULL;
+ }
+ return pCex;
+
+}
+
+/**Function*************************************************************
+
+ Synopsis [Make the trivial counter-example for the trivially asserted output.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cex_t * Ssw_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut )
+{
+ Ssw_Cex_t * pCex;
+ int nTruePis, nTruePos, iPo, iFrame;
+ assert( Aig_ManRegNum(pAig) > 0 );
+ nTruePis = Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig);
+ nTruePos = Aig_ManPoNum(pAig)-Aig_ManRegNum(pAig);
+ iPo = iFrameOut % nTruePos;
+ iFrame = iFrameOut / nTruePos;
+ // allocate the counter example
+ pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), nTruePis, iFrame + 1 );
+ pCex->iPo = iPo;
+ pCex->iFrame = iFrame;
+ return pCex;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Make the trivial counter-example for the trivially asserted output.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Ssw_Cex_t * Ssw_SmlDupCounterExample( Ssw_Cex_t * p, int nRegsNew )
+{
+ Ssw_Cex_t * pCex;
+ int i;
+ pCex = Ssw_SmlAllocCounterExample( nRegsNew, p->nPis, p->iFrame+1 );
+ pCex->iPo = p->iPo;
+ pCex->iFrame = p->iFrame;
+ for ( i = p->nRegs; i < p->nBits; i++ )
+ if ( Aig_InfoHasBit(p->pData, i) )
+ Aig_InfoSetBit( pCex->pData, pCex->nRegs + i - p->nRegs );
+ return pCex;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resimulates the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_SmlWriteCounterExample( FILE * pFile, Aig_Man_t * pAig, Ssw_Cex_t * p )
+{
+ Ssw_Sml_t * pSml;
+ Aig_Obj_t * pObj;
+ int RetValue, i, k, iBit;
+ unsigned * pSims;
+ assert( Aig_ManRegNum(pAig) > 0 );
+ assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) );
+ // start a new sequential simulator
+ pSml = Ssw_SmlStart( pAig, 0, p->iFrame+1, 1 );
+ // assign simulation info for the registers
+ iBit = 0;
+ Saig_ManForEachLo( pAig, pObj, i )
+// Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 );
+ Ssw_SmlObjAssignConst( pSml, pObj, 0, 0 );
+ // assign simulation info for the primary inputs
+ iBit = p->nRegs;
+ for ( i = 0; i <= p->iFrame; i++ )
+ Saig_ManForEachPi( pAig, pObj, k )
+ Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i );
+ assert( iBit == p->nBits );
+ // run random simulation
+ Ssw_SmlSimulateOne( pSml );
+ // check if the given output has failed
+ RetValue = !Ssw_SmlNodeIsZero( pSml, Aig_ManPo(pAig, p->iPo) );
+
+ // write the output file
+ for ( i = 0; i <= p->iFrame; i++ )
+ {
+/*
+ Saig_ManForEachLo( pAig, pObj, k )
+ {
+ pSims = Ssw_ObjSim(pSml, pObj->Id);
+ fprintf( pFile, "%d", (int)(pSims[i] != 0) );
+ }
+ fprintf( pFile, " " );
+*/
+ Saig_ManForEachPi( pAig, pObj, k )
+ {
+ pSims = Ssw_ObjSim(pSml, pObj->Id);
+ fprintf( pFile, "%d", (int)(pSims[i] != 0) );
+ }
+/*
+ fprintf( pFile, " " );
+ Saig_ManForEachPo( pAig, pObj, k )
+ {
+ pSims = Ssw_ObjSim(pSml, pObj->Id);
+ fprintf( pFile, "%d", (int)(pSims[i] != 0) );
+ }
+ fprintf( pFile, " " );
+ Saig_ManForEachLi( pAig, pObj, k )
+ {
+ pSims = Ssw_ObjSim(pSml, pObj->Id);
+ fprintf( pFile, "%d", (int)(pSims[i] != 0) );
+ }
+*/
+ fprintf( pFile, "\n" );
+ }
+
+ Ssw_SmlStop( pSml );
+ return RetValue;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ssw_old/sswSimSat.c b/src/aig/ssw_old/sswSimSat.c
new file mode 100644
index 00000000..cbb6d0c1
--- /dev/null
+++ b/src/aig/ssw_old/sswSimSat.c
@@ -0,0 +1,199 @@
+/**CFile****************************************************************
+
+ FileName [sswSimSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [Performs resimulation using counter-examples.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswSimSat.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Handle the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManResimulateBit( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr )
+{
+ Aig_Obj_t * pObj;
+ int i, RetValue1, RetValue2, clk = clock();
+ // set the PI simulation information
+ Aig_ManConst1(p->pAig)->fMarkB = 1;
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ pObj->fMarkB = Aig_InfoHasBit( p->pPatWords, i );
+ // simulate internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) )
+ & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) );
+ // check equivalence classes
+ RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 0 );
+ RetValue2 = Ssw_ClassesRefine( p->ppClasses, 0 );
+ // make sure refinement happened
+ if ( Aig_ObjIsConst1(pRepr) )
+ {
+ assert( RetValue1 );
+ if ( RetValue1 == 0 )
+ printf( "\nSsw_ManResimulateBit() Error: RetValue1 does not hold.\n" );
+ }
+ else
+ {
+ assert( RetValue2 );
+ if ( RetValue2 == 0 )
+ printf( "\nSsw_ManResimulateBit() Error: RetValue2 does not hold.\n" );
+ }
+p->timeSimSat += clock() - clk;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verifies the result of simulation.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManResimulateWordVerify( Ssw_Man_t * p, int f )
+{
+ Aig_Obj_t * pObj, * pObjFraig;
+ unsigned uWord;
+ int Value1, Value2;
+ int i, nVarNum, Counter = 0;
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ {
+ pObjFraig = Ssw_ObjFrame( p, pObj, f );
+ if ( pObjFraig == NULL )
+ continue;
+ nVarNum = Ssw_ObjSatNum( p, Aig_Regular(pObjFraig) );
+ if ( nVarNum == 0 )
+ continue;
+ Value1 = Ssw_ManGetSatVarValue( p, pObj, f );
+ uWord = Ssw_SmlObjGetWord( p->pSml, pObj, 0, 0 );
+ Value2 = ((uWord != 0) ^ pObj->fPhase);
+ Counter += (Value1 != Value2);
+ if ( Value1 != Value2 )
+ {
+/*
+ int Value1f = Ssw_ManGetSatVarValue( p, Aig_ObjFanin0(pObj), f );
+ int Value2f = Ssw_ManGetSatVarValue( p, Aig_ObjFanin1(pObj), f );
+*/
+ int x = 0;
+ int Value3 = Ssw_ManGetSatVarValue( p, pObj, f );
+ }
+ }
+ if ( Counter )
+ printf( "Counter = %d.\n", Counter );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Handle the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManResimulateWord( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f )
+{
+ int RetValue1, RetValue2, clk = clock();
+ // set the PI simulation information
+ Ssw_SmlAssignDist1Plus( p->pSml, p->pPatWords );
+ // simulate internal nodes
+ Ssw_SmlSimulateOne( p->pSml );
+ Ssw_ManResimulateWordVerify( p, f );
+
+ // check equivalence classes
+ RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 );
+ RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 );
+ // make sure refinement happened
+ if ( Aig_ObjIsConst1(pRepr) )
+ {
+ assert( RetValue1 );
+ if ( RetValue1 == 0 )
+ printf( "\nSsw_ManResimulateWord() Error: RetValue1 does not hold.\n" );
+ }
+ else
+ {
+ assert( RetValue2 );
+ if ( RetValue2 == 0 )
+ printf( "\nSsw_ManResimulateWord() Error: RetValue2 does not hold.\n" );
+ }
+p->timeSimSat += clock() - clk;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Handle the counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManResimulateWord2( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f )
+{
+ int RetValue1, RetValue2, clk = clock();
+ // set the PI simulation information
+ Ssw_SmlAssignDist1Plus( p->pSml, p->pPatWords2 );
+ // simulate internal nodes
+ Ssw_SmlSimulateOne( p->pSml );
+ Ssw_ManResimulateWordVerify( p, f );
+
+ // check equivalence classes
+ RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 );
+ RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 );
+ // make sure refinement happened
+ if ( Aig_ObjIsConst1(pRepr) )
+ {
+ assert( RetValue1 );
+ if ( RetValue1 == 0 )
+ printf( "\nSsw_ManResimulateWord() Error: RetValue1 does not hold.\n" );
+ }
+ else
+ {
+ assert( RetValue2 );
+ if ( RetValue2 == 0 )
+ printf( "\nSsw_ManResimulateWord() Error: RetValue2 does not hold.\n" );
+ }
+p->timeSimSat += clock() - clk;
+
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ssw_old/sswSweep.c b/src/aig/ssw_old/sswSweep.c
new file mode 100644
index 00000000..b9d4ad63
--- /dev/null
+++ b/src/aig/ssw_old/sswSweep.c
@@ -0,0 +1,473 @@
+/**CFile****************************************************************
+
+ FileName [sswSweep.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [One round of SAT sweeping.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswSweep.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+#include "bar.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Mark nodes affected by sweep in the previous iteration.]
+
+ Description [Assumes that affected nodes are in p->ppClasses->vRefined.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_ManSweepMarkRefinement( Ssw_Man_t * p )
+{
+ Vec_Ptr_t * vRefined, * vSupp;
+ Aig_Obj_t * pObj, * pObjLo, * pObjLi;
+ int i, k;
+ vRefined = Ssw_ClassesGetRefined( p->ppClasses );
+ if ( Vec_PtrSize(vRefined) == 0 )
+ {
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ pObj->fMarkA = 1;
+ return;
+ }
+ // mark the nodes to be refined
+ Aig_ManCleanMarkA( p->pAig );
+ Vec_PtrForEachEntry( vRefined, pObj, i )
+ {
+ if ( Aig_ObjIsPi(pObj) )
+ {
+ pObj->fMarkA = 1;
+ continue;
+ }
+ assert( Aig_ObjIsNode(pObj) );
+ vSupp = Aig_Support( p->pAig, pObj );
+ Vec_PtrForEachEntry( vSupp, pObjLo, k )
+ pObjLo->fMarkA = 1;
+ Vec_PtrFree( vSupp );
+ }
+ // mark refinement
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ pObj->fMarkA = Aig_ObjFanin0(pObj)->fMarkA | Aig_ObjFanin1(pObj)->fMarkA;
+ Saig_ManForEachLi( p->pAig, pObj, i )
+ pObj->fMarkA |= Aig_ObjFanin0(pObj)->fMarkA;
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ pObjLo->fMarkA |= pObjLi->fMarkA;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Retrives value of the PI in the original AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManGetSatVarValue( Ssw_Man_t * p, Aig_Obj_t * pObj, int f )
+{
+ Aig_Obj_t * pObjFraig;
+ int nVarNum, Value;
+// assert( Aig_ObjIsPi(pObj) );
+ pObjFraig = Ssw_ObjFrame( p, pObj, f );
+ nVarNum = Ssw_ObjSatNum( p, Aig_Regular(pObjFraig) );
+ assert( nVarNum > 0 );
+ if ( nVarNum == 0 )
+ printf( "Variable is not assigned.\n" );
+ Value = (!nVarNum)? 0 : (Aig_IsComplement(pObjFraig) ^ sat_solver_var_value( p->pSat, nVarNum ));
+// Value = (Aig_IsComplement(pObjFraig) ^ ((!nVarNum)? 0 : sat_solver_var_value( p->pSat, nVarNum )));
+// Value = (!nVarNum)? Aig_ManRandom(0) & 1 : (Aig_IsComplement(pObjFraig) ^ sat_solver_var_value( p->pSat, nVarNum ));
+ if ( p->pPars->fPolarFlip )
+ {
+ if ( Aig_Regular(pObjFraig)->fPhase ) Value ^= 1;
+ }
+ return Value;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Copy pattern from the solver into the internal storage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSavePatternAig( Ssw_Man_t * p, int f )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ if ( Ssw_ManGetSatVarValue( p, pObj, f ) )
+ Aig_InfoSetBit( p->pPatWords, i );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Copy pattern from the solver into the internal storage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSavePatternAig2( Ssw_Man_t * p, int f )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ memset( p->pPatWords2, 0, sizeof(unsigned) * p->nPatWords );
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ if ( Ssw_ManGetSatVarValue( p, pObj, f ) )
+ Aig_InfoSetBit( p->pPatWords2, i );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Copy pattern from the solver into the internal storage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Ssw_SmlSavePatternAigPhase( Ssw_Man_t * p, int f )
+{
+ Aig_Obj_t * pObj;
+ int i;
+ memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ if ( Aig_ObjPhaseReal( Ssw_ObjFrame(p, pObj, f) ) )
+ Aig_InfoSetBit( p->pPatWords, i );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for one node.]
+
+ Description [Returns the fraiged node.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc )
+{
+ Aig_Obj_t * pObjRepr, * pObjFraig, * pObjFraig2, * pObjReprFraig;
+ int RetValue;
+ // get representative of this class
+ pObjRepr = Aig_ObjRepr( p->pAig, pObj );
+ if ( pObjRepr == NULL )
+ return 0;
+ // get the fraiged node
+ pObjFraig = Ssw_ObjFrame( p, pObj, f );
+ // get the fraiged representative
+ pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, f );
+ // check if constant 0 pattern distinquishes these nodes
+ assert( pObjFraig != NULL && pObjReprFraig != NULL );
+ if ( (pObj->fPhase == pObjRepr->fPhase) != (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) )
+ {
+ p->nStrangers++;
+ Ssw_SmlSavePatternAigPhase( p, f );
+ }
+ else
+ {
+ // if the fraiged nodes are the same, return
+ if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) )
+ return 0;
+ // count the number of skipped calls
+ if ( !pObj->fMarkA && !pObjRepr->fMarkA )
+ p->nRefSkip++;
+ else
+ p->nRefUse++;
+ // call equivalence checking
+ if ( p->pPars->fSkipCheck && !fBmc && !pObj->fMarkA && !pObjRepr->fMarkA )
+ RetValue = 1;
+ else if ( Aig_Regular(pObjFraig) != Aig_ManConst1(p->pFrames) )
+ RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
+ else
+ RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjFraig), Aig_Regular(pObjReprFraig) );
+ if ( RetValue == 1 ) // proved equivalent
+ {
+ pObjFraig2 = Aig_NotCond( pObjReprFraig, pObj->fPhase ^ pObjRepr->fPhase );
+ Ssw_ObjSetFrame( p, pObj, f, pObjFraig2 );
+ return 0;
+ }
+ if ( RetValue == -1 ) // timed out
+ {
+ Ssw_ClassesRemoveNode( p->ppClasses, pObj );
+ return 1;
+ }
+ // check if skipping calls works correctly
+ if ( p->pPars->fSkipCheck && !fBmc && !pObj->fMarkA && !pObjRepr->fMarkA )
+ {
+ assert( 0 );
+ printf( "\nSsw_ManSweepNode(): Error!\n" );
+ }
+ // disproved the equivalence
+ Ssw_SmlSavePatternAig( p, f );
+ }
+ if ( !fBmc && p->pPars->fUniqueness && p->pPars->nFramesK > 1 &&
+ Ssw_ManUniqueOne( p, pObjRepr, pObj ) && p->iOutputLit == -1 )
+ {
+ if ( Ssw_ManUniqueAddConstraint( p, p->vCommon, 0, 1 ) )
+ {
+ int RetValue2 = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
+ p->iOutputLit = -1;
+
+ {
+ int Flag = 0;
+ if ( Flag )
+ {
+ Aig_Obj_t * pFan0 = Aig_ObjFanin0(pObj);
+ Aig_Obj_t * pFan1 = Aig_ObjFanin1(pObj);
+ Aig_Obj_t * pFan00 = Aig_ObjFanin0(pFan0);
+ Aig_Obj_t * pFan01 = Aig_ObjFanin1(pFan0);
+ Aig_Obj_t * pFan10 = Aig_ObjFanin0(pFan1);
+ Aig_Obj_t * pFan11 = Aig_ObjFanin1(pFan1);
+ }
+ }
+
+ if ( RetValue2 == 0 )
+ {
+ int x = Ssw_ManUniqueOne( p, pObjRepr, pObj );
+// Ssw_SmlSavePatternAig2( p, f );
+// Ssw_ManResimulateWord2( p, pObj, pObjRepr, f );
+ Ssw_SmlSavePatternAig( p, f );
+ Ssw_ManResimulateWord( p, pObj, pObjRepr, f );
+ if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr )
+ printf( "Ssw_ManSweepNode(): Refinement did not happen!!!!!!!!!!!!!!!!!!!!.\n" );
+ return 1;
+ }
+ return 0;
+
+
+/*
+ int RetValue;
+ assert( p->iOutputLit > -1 );
+ RetValue = Ssw_ManSweepNode( p, pObj, f, 0 );
+ p->iOutputLit = -1;
+ return RetValue;
+*/
+ }
+ }
+ if ( p->pPars->nConstrs == 0 )
+ Ssw_ManResimulateWord( p, pObj, pObjRepr, f );
+ else
+ Ssw_ManResimulateBit( p, pObj, pObjRepr );
+ assert( Aig_ObjRepr( p->pAig, pObj ) != pObjRepr );
+ if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr )
+ printf( "Ssw_ManSweepNode(): Refinement did not happen.\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweepBmc( Ssw_Man_t * p )
+{
+ Bar_Progress_t * pProgress = NULL;
+ Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo;
+ int i, f, clk;
+clk = clock();
+
+ // start initialized timeframes
+ p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrames) );
+
+ // sweep internal nodes
+ p->fRefined = 0;
+ if ( p->pPars->fVerbose )
+ pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
+ Ssw_ManStartSolver( p );
+ for ( f = 0; f < p->pPars->nFramesK; f++ )
+ {
+ // map constants and PIs
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ {
+ pObjNew = Aig_ObjCreatePi(p->pFrames);
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ Ssw_CnfNodeAddToSolver( p, Aig_Regular(pObjNew) );
+ }
+ // sweep internal nodes
+ Aig_ManForEachNode( p->pAig, pObj, i )
+ {
+ if ( p->pPars->fVerbose )
+ Bar_ProgressUpdate( pProgress, Aig_ManObjNumMax(p->pAig) * f + i, NULL );
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 1 );
+ }
+ // quit if this is the last timeframe
+ if ( f == p->pPars->nFramesK - 1 )
+ break;
+ // transfer latch input to the latch outputs
+ // build logic cones for register outputs
+ Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
+ {
+ pObjNew = Ssw_ObjChild0Fra(p, pObjLi,f);
+ Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew );
+ Ssw_CnfNodeAddToSolver( p, Aig_Regular(pObjNew) );
+ }
+ }
+ if ( p->pPars->fVerbose )
+ Bar_ProgressStop( pProgress );
+
+ // cleanup
+// Ssw_ClassesCheck( p->ppClasses );
+p->timeBmc += clock() - clk;
+ return p->fRefined;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs fraiging for the internal nodes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManSweep( Ssw_Man_t * p )
+{
+ Bar_Progress_t * pProgress = NULL;
+ Aig_Obj_t * pObj, * pObj2, * pObjNew;
+ int nConstrPairs, clk, i, f;
+ int v;
+
+ // perform speculative reduction
+clk = clock();
+ // create timeframes
+ p->pFrames = Ssw_FramesWithClasses( p );
+ // add constraints
+ Ssw_ManStartSolver( p );
+// nConstrPairs = Aig_ManPoNum(p->pFrames)-Aig_ManRegNum(p->pAig);
+ nConstrPairs = Aig_ManPoNum(p->pFrames)-p->nFrames*Aig_ManRegNum(p->pAig);
+ assert( (nConstrPairs & 1) == 0 );
+ for ( i = 0; i < nConstrPairs; i += 2 )
+ {
+ pObj = Aig_ManPo( p->pFrames, i );
+ pObj2 = Aig_ManPo( p->pFrames, i+1 );
+ Ssw_NodesAreConstrained( p, Aig_ObjChild0(pObj), Aig_ObjChild0(pObj2) );
+ }
+/*
+ // build logic cones for register inputs
+ for ( i = 0; i < Aig_ManRegNum(p->pAig); i++ )
+ {
+ pObj = Aig_ManPo( p->pFrames, nConstrPairs + i );
+ Ssw_CnfNodeAddToSolver( p, Aig_ObjFanin0(pObj) );
+ }
+*/
+p->timeReduce += clock() - clk;
+
+ // mark nodes that do not have to be refined
+clk = clock();
+ if ( p->pPars->fSkipCheck )
+ Ssw_ManSweepMarkRefinement( p );
+p->timeMarkCones += clock() - clk;
+
+//Ssw_ManUnique( p );
+
+ // map constants and PIs of the last frame
+ f = p->pPars->nFramesK;
+ Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
+ Saig_ManForEachPi( p->pAig, pObj, i )
+ Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(p->pFrames) );
+////
+ // bring up the previous frames
+// if ( p->pPars->fUniqueness )
+ for ( v = 0; v <= f; v++ )
+// Saig_ManForEachLo( p->pAig, pObj, i )
+ Aig_ManForEachPi( p->pAig, pObj, i )
+ {
+/*
+ if ( i == 53 && v == 1 )
+ {
+ int x = 0;
+ }
+*/
+ Ssw_CnfNodeAddToSolver( p, Aig_Regular(Ssw_ObjFrame(p, pObj, v)) );
+ }
+////
+ sat_solver_simplify( p->pSat );
+ // make sure LOs are assigned
+ Saig_ManForEachLo( p->pAig, pObj, i )
+ assert( Ssw_ObjFrame( p, pObj, f ) != NULL );
+ // sweep internal nodes
+ p->fRefined = 0;
+ p->nSatFailsReal = 0;
+ p->nRefUse = p->nRefSkip = 0;
+ p->nUniques = 0;
+ Ssw_ClassesClearRefined( p->ppClasses );
+ if ( p->pPars->fVerbose )
+ pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) );
+ Aig_ManForEachObj( p->pAig, pObj, i )
+ {
+ if ( p->pPars->fVerbose )
+ Bar_ProgressUpdate( pProgress, i, NULL );
+ if ( Saig_ObjIsLo(p->pAig, pObj) )
+ p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 0 );
+ else if ( Aig_ObjIsNode(pObj) )
+ {
+ pObj->fMarkA = Aig_ObjFanin0(pObj)->fMarkA | Aig_ObjFanin1(pObj)->fMarkA;
+ pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
+ Ssw_ObjSetFrame( p, pObj, f, pObjNew );
+ p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 0 );
+ }
+ }
+ p->nSatFailsTotal += p->nSatFailsReal;
+ if ( p->pPars->fVerbose )
+ Bar_ProgressStop( pProgress );
+
+ // cleanup
+// Ssw_ClassesCheck( p->ppClasses );
+ return p->fRefined;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/aig/ssw_old/sswUnique.c b/src/aig/ssw_old/sswUnique.c
new file mode 100644
index 00000000..2beeed09
--- /dev/null
+++ b/src/aig/ssw_old/sswUnique.c
@@ -0,0 +1,290 @@
+/**CFile****************************************************************
+
+ FileName [sswSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Inductive prover with constraints.]
+
+ Synopsis [On-demand uniqueness constraints.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - September 1, 2008.]
+
+ Revision [$Id: sswSat.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "sswInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Returns the result of merging the two vectors.]
+
+ Description [Assumes that the vectors are sorted in the increasing order.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrTwoMerge( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr )
+{
+ Aig_Obj_t ** pBeg = (Aig_Obj_t **)vArr->pArray;
+ Aig_Obj_t ** pBeg1 = (Aig_Obj_t **)vArr1->pArray;
+ Aig_Obj_t ** pBeg2 = (Aig_Obj_t **)vArr2->pArray;
+ Aig_Obj_t ** pEnd1 = (Aig_Obj_t **)vArr1->pArray + vArr1->nSize;
+ Aig_Obj_t ** pEnd2 = (Aig_Obj_t **)vArr2->pArray + vArr2->nSize;
+ Vec_PtrGrow( vArr, Vec_PtrSize(vArr1) + Vec_PtrSize(vArr2) );
+ pBeg = (Aig_Obj_t **)vArr->pArray;
+ while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
+ {
+ if ( (*pBeg1)->Id == (*pBeg2)->Id )
+ *pBeg++ = *pBeg1++, pBeg2++;
+ else if ( (*pBeg1)->Id < (*pBeg2)->Id )
+ *pBeg++ = *pBeg1++;
+ else
+ *pBeg++ = *pBeg2++;
+ }
+ while ( pBeg1 < pEnd1 )
+ *pBeg++ = *pBeg1++;
+ while ( pBeg2 < pEnd2 )
+ *pBeg++ = *pBeg2++;
+ vArr->nSize = pBeg - (Aig_Obj_t **)vArr->pArray;
+ assert( vArr->nSize <= vArr->nCap );
+ assert( vArr->nSize >= vArr1->nSize );
+ assert( vArr->nSize >= vArr2->nSize );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the result of merging the two vectors.]
+
+ Description [Assumes that the vectors are sorted in the increasing order.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_PtrTwoCommon( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr )
+{
+ Aig_Obj_t ** pBeg = (Aig_Obj_t **)vArr->pArray;
+ Aig_Obj_t ** pBeg1 = (Aig_Obj_t **)vArr1->pArray;
+ Aig_Obj_t ** pBeg2 = (Aig_Obj_t **)vArr2->pArray;
+ Aig_Obj_t ** pEnd1 = (Aig_Obj_t **)vArr1->pArray + vArr1->nSize;
+ Aig_Obj_t ** pEnd2 = (Aig_Obj_t **)vArr2->pArray + vArr2->nSize;
+ Vec_PtrGrow( vArr, AIG_MIN( Vec_PtrSize(vArr1), Vec_PtrSize(vArr2) ) );
+ pBeg = (Aig_Obj_t **)vArr->pArray;
+ while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
+ {
+ if ( (*pBeg1)->Id == (*pBeg2)->Id )
+ *pBeg++ = *pBeg1++, pBeg2++;
+ else if ( (*pBeg1)->Id < (*pBeg2)->Id )
+// *pBeg++ = *pBeg1++;
+ pBeg1++;
+ else
+// *pBeg++ = *pBeg2++;
+ pBeg2++;
+ }
+// while ( pBeg1 < pEnd1 )
+// *pBeg++ = *pBeg1++;
+// while ( pBeg2 < pEnd2 )
+// *pBeg++ = *pBeg2++;
+ vArr->nSize = pBeg - (Aig_Obj_t **)vArr->pArray;
+ assert( vArr->nSize <= vArr->nCap );
+ assert( vArr->nSize <= vArr1->nSize );
+ assert( vArr->nSize <= vArr2->nSize );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns 1 if uniqueness constraints can be added.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj )
+{
+ int fVerbose = 1;
+ Aig_Obj_t * ppObjs[2], * pTemp;
+ Vec_Ptr_t * vSupp, * vSupp2;
+ int i, k, Value0, Value1, RetValue;
+ assert( p->pPars->nFramesK > 1 );
+
+ vSupp = Vec_PtrAlloc( 100 );
+ vSupp2 = Vec_PtrAlloc( 100 );
+ Vec_PtrClear( p->vCommon );
+
+ // compute the first support in terms of LOs
+ ppObjs[0] = pRepr;
+ ppObjs[1] = pObj;
+ Aig_SupportNodes( p->pAig, ppObjs, 2, vSupp );
+ // modify support to be in terms of LIs
+ k = 0;
+ Vec_PtrForEachEntry( vSupp, pTemp, i )
+ if ( Saig_ObjIsLo(p->pAig, pTemp) )
+ Vec_PtrWriteEntry( vSupp, k++, Saig_ObjLoToLi(p->pAig, pTemp) );
+ Vec_PtrShrink( vSupp, k );
+ // compute the support of support
+ Aig_SupportNodes( p->pAig, (Aig_Obj_t **)Vec_PtrArray(vSupp), Vec_PtrSize(vSupp), vSupp2 );
+ // return support to LO
+ Vec_PtrForEachEntry( vSupp, pTemp, i )
+ Vec_PtrWriteEntry( vSupp, i, Saig_ObjLiToLo(p->pAig, pTemp) );
+ // find the number of common vars
+ Vec_PtrSort( vSupp, Aig_ObjCompareIdIncrease );
+ Vec_PtrSort( vSupp2, Aig_ObjCompareIdIncrease );
+ Vec_PtrTwoCommon( vSupp, vSupp2, p->vCommon );
+// Vec_PtrTwoMerge( vSupp, vSupp2, p->vCommon );
+
+/*
+ {
+ Vec_Ptr_t * vNew = Vec_PtrDup(vSupp);
+ Vec_PtrUniqify( vNew, Aig_ObjCompareIdIncrease );
+ if ( Vec_PtrSize(vNew) != Vec_PtrSize(vSupp) )
+ printf( "Not unique!\n" );
+ Vec_PtrFree( vNew );
+ Vec_PtrForEachEntry( vSupp, pTemp, i )
+ printf( "%d ", pTemp->Id );
+ printf( "\n" );
+ }
+ {
+ Vec_Ptr_t * vNew = Vec_PtrDup(vSupp2);
+ Vec_PtrUniqify( vNew, Aig_ObjCompareIdIncrease );
+ if ( Vec_PtrSize(vNew) != Vec_PtrSize(vSupp2) )
+ printf( "Not unique!\n" );
+ Vec_PtrFree( vNew );
+ Vec_PtrForEachEntry( vSupp2, pTemp, i )
+ printf( "%d ", pTemp->Id );
+ printf( "\n" );
+ }
+ {
+ Vec_Ptr_t * vNew = Vec_PtrDup(p->vCommon);
+ Vec_PtrUniqify( vNew, Aig_ObjCompareIdIncrease );
+ if ( Vec_PtrSize(vNew) != Vec_PtrSize(p->vCommon) )
+ printf( "Not unique!\n" );
+ Vec_PtrFree( vNew );
+ Vec_PtrForEachEntry( p->vCommon, pTemp, i )
+ printf( "%d ", pTemp->Id );
+ printf( "\n" );
+ }
+*/
+
+ if ( fVerbose )
+ printf( "Node = %5d : One = %3d. Two = %3d. Common = %3d. ",
+ Aig_ObjId(pObj), Vec_PtrSize(vSupp), Vec_PtrSize(vSupp2), Vec_PtrSize(p->vCommon) );
+
+// Vec_PtrClear( vSupp );
+// Vec_PtrForEachEntry( vSupp2, pTemp, i )
+// Vec_PtrPush( vSupp, pTemp );
+
+ // check the current values
+ RetValue = 1;
+// Vec_PtrForEachEntry( p->vCommon, pTemp, i )
+ Vec_PtrForEachEntry( vSupp, pTemp, i )
+ {
+ Value0 = Ssw_ManGetSatVarValue( p, pTemp, 0 );
+ Value1 = Ssw_ManGetSatVarValue( p, pTemp, 1 );
+ if ( Value0 != Value1 )
+ RetValue = 0;
+ if ( fVerbose )
+ printf( "%d", Value0 ^ Value1 );
+ }
+ if ( Vec_PtrSize(p->vCommon) == 0 )
+ RetValue = 0;
+
+ Vec_PtrForEachEntry( vSupp, pTemp, i )
+ printf( " %d", pTemp->Id );
+
+ if ( fVerbose )
+ printf( "\n" );
+
+
+ Vec_PtrClear( p->vCommon );
+ Vec_PtrForEachEntry( vSupp, pTemp, i )
+ Vec_PtrPush( p->vCommon, pTemp );
+
+ Vec_PtrFree( vSupp );
+ Vec_PtrFree( vSupp2 );
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Returns the output of the uniqueness constraint.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int f2 )
+{
+ Aig_Obj_t * pObj, * pObj1New, * pObj2New, * pMiter, * pTotal;
+ int i, pLits[2];
+// int RetValue;
+ assert( Vec_PtrSize(vCommon) > 0 );
+ // generate the constraint
+ pTotal = Aig_ManConst0(p->pFrames);
+ Vec_PtrForEachEntry( vCommon, pObj, i )
+ {
+ assert( Saig_ObjIsLo(p->pAig, pObj) );
+ pObj1New = Ssw_ObjFrame( p, pObj, f1 );
+ pObj2New = Ssw_ObjFrame( p, pObj, f2 );
+ pMiter = Aig_Exor( p->pFrames, pObj1New, pObj2New );
+ pTotal = Aig_Or( p->pFrames, pTotal, pMiter );
+ }
+/*
+ if ( Aig_ObjIsConst1(Aig_Regular(pTotal)) )
+ {
+// printf( "Skipped\n" );
+ return 0;
+ }
+*/
+ p->nUniques++;
+ // create CNF
+// {
+// int Num1 = p->nSatVars;
+ Ssw_CnfNodeAddToSolver( p, Aig_Regular(pTotal) );
+// printf( "Created variable %d while vars are %d. (diff = %d)\n",
+// Ssw_ObjSatNum( p, Aig_Regular(pTotal) ), p->nSatVars, p->nSatVars - Num1 );
+// }
+ // add output constraint
+ pLits[0] = toLitCond( Ssw_ObjSatNum(p,Aig_Regular(pTotal)), Aig_IsComplement(pTotal) );
+/*
+ RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 1 );
+ assert( RetValue );
+ // simplify the solver
+ if ( p->pSat->qtail != p->pSat->qhead )
+ {
+ RetValue = sat_solver_simplify(p->pSat);
+ assert( RetValue != 0 );
+ }
+*/
+ assert( p->iOutputLit == -1 );
+ p->iOutputLit = pLits[0];
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index 4f46f3a2..50fb11ac 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -254,6 +254,7 @@ static int Abc_CommandAbc8Zero ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandAbc8Cec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc8DSec ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbcTestNew ( Abc_Frame_t * pAbc, int argc, char ** argv );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -518,6 +519,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC8", "*cec", Abc_CommandAbc8Cec, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*dsec", Abc_CommandAbc8DSec, 0 );
+ Cmd_CommandAdd( pAbc, "Various", "testnew", Abc_CommandAbcTestNew, 0 );
// Cmd_CommandAdd( pAbc, "Verification", "trace_start", Abc_CommandTraceStart, 0 );
// Cmd_CommandAdd( pAbc, "Verification", "trace_check", Abc_CommandTraceCheck, 0 );
@@ -4919,22 +4921,24 @@ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;//, * pNtkRes;
- int fComb;
+ int fSeq;
int c;
extern int Abc_NtkDemiter( Abc_Ntk_t * pNtk );
+ extern int Abc_NtkDarDemiter( Abc_Ntk_t * pNtk );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
+ fSeq = 1;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "sh" ) ) != EOF )
{
switch ( c )
{
- case 'c':
- fComb ^= 1;
+ case 's':
+ fSeq ^= 1;
break;
default:
goto usage;
@@ -4947,12 +4951,6 @@ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
- if ( Abc_NtkPoNum(pNtk) != 1 )
- {
- fprintf( pErr, "The network is not a miter.\n" );
- return 1;
- }
-
if ( !Abc_NodeIsExorType(Abc_ObjFanin0(Abc_NtkPo(pNtk,0))) )
{
fprintf( pErr, "The miter's PO is not an EXOR.\n" );
@@ -4960,19 +4958,35 @@ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// get the new network
- if ( !Abc_NtkDemiter( pNtk ) )
+ if ( fSeq )
{
- fprintf( pErr, "Demitering has failed.\n" );
- return 1;
+ if ( !Abc_NtkDarDemiter( pNtk ) )
+ {
+ fprintf( pErr, "Demitering has failed.\n" );
+ return 1;
+ }
+ }
+ else
+ {
+ if ( Abc_NtkPoNum(pNtk) != 1 )
+ {
+ fprintf( pErr, "The network is not a single-output miter.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkDemiter( pNtk ) )
+ {
+ fprintf( pErr, "Demitering has failed.\n" );
+ return 1;
+ }
}
// replace the current network
// Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
return 0;
usage:
- fprintf( pErr, "usage: demiter [-h]\n" );
+ fprintf( pErr, "usage: demiter [-sh]\n" );
fprintf( pErr, "\t removes topmost EXOR from the miter to create two POs\n" );
-// fprintf( pErr, "\t-c : computes combinational miter (latches as POs) [default = %s]\n", fComb? "yes": "no" );
+ fprintf( pErr, "\t-s : applied multi-output algorithm [default = %s]\n", fSeq? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
@@ -7720,7 +7734,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
// extern void Aig_ProcedureTest();
extern void Abc_NtkDarTest( Abc_Ntk_t * pNtk );
extern Abc_Ntk_t * Abc_NtkDarTestNtk( Abc_Ntk_t * pNtk );
-
+ extern int Ssw_SecSpecialMiter( Aig_Man_t * pMiter, int fVerbose );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
@@ -7922,6 +7936,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
*/
+/*
pNtkRes = Abc_NtkDarTestNtk( pNtk );
if ( pNtkRes == NULL )
{
@@ -7930,6 +7945,9 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+*/
+
+ Abc_NtkDarTest( pNtk );
return 0;
usage:
@@ -13541,7 +13559,7 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults
Ssw_ManSetDefaultParams( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLNSplsfuvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLNSplsfuvwh" ) ) != EOF )
{
switch ( c )
{
@@ -13640,6 +13658,9 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'v':
pPars->fVerbose ^= 1;
break;
+ case 'w':
+ pPars->fFlopVerbose ^= 1;
+ break;
case 'h':
goto usage;
default:
@@ -13689,7 +13710,7 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- fprintf( pErr, "usage: scorr [-PQFCLNS <num>] [-plsfuvh]\n" );
+ fprintf( pErr, "usage: scorr [-PQFCLNS <num>] [-plsfuvwh]\n" );
fprintf( pErr, "\t performs sequential sweep using K-step induction\n" );
fprintf( pErr, "\t-P num : max partition size (0 = no partitioning) [default = %d]\n", pPars->nPartSize );
fprintf( pErr, "\t-Q num : partition overlap (0 = no overlap) [default = %d]\n", pPars->nOverSize );
@@ -13704,6 +13725,7 @@ usage:
fprintf( pErr, "\t-f : toggle filtering using interative BMC [default = %s]\n", pPars->fSemiFormal? "yes": "no" );
fprintf( pErr, "\t-u : toggle using uniqueness constraints [default = %s]\n", pPars->fUniqueness? "yes": "no" );
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
+ fprintf( pErr, "\t-w : toggle printout of flop equivalences [default = %s]\n", pPars->fFlopVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
@@ -19634,6 +19656,64 @@ usage:
}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbcTestNew( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern int Abc_NtkTestProcedure( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 );
+
+ Abc_Ntk_t * pNtk;
+ int c;
+
+ pNtk = Abc_FrameReadNtk(pAbc);
+
+ // set defaults
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( pNtk == NULL )
+ {
+ fprintf( stdout, "Empty network.\n" );
+ return 1;
+ }
+
+ if ( !Abc_NtkIsStrash( pNtk) )
+ {
+ fprintf( stdout, "The current network is not an AIG. Cannot continue.\n" );
+ return 1;
+ }
+
+// Abc_NtkTestProcedure( pNtk, NULL );
+
+ return 0;
+
+usage:
+ fprintf( stdout, "usage: testnew [-h]\n" );
+ fprintf( stdout, "\t new testing procedure\n" );
+ fprintf( stdout, "\t-h : print the command usage\n");
+ return 1;
+}
+
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/abci/abc.zip b/src/base/abci/abc.zip
new file mode 100644
index 00000000..34df9a63
--- /dev/null
+++ b/src/base/abci/abc.zip
Binary files differ
diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c
index 98228c56..c64fb0f5 100644
--- a/src/base/abci/abcDar.c
+++ b/src/base/abci/abcDar.c
@@ -1240,6 +1240,96 @@ PRT( "Initial fraiging time", clock() - clk );
/**Function*************************************************************
+ Synopsis [Print Latch Equivalence Classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPrintLatchEquivClasses( Abc_Ntk_t * pNtk, Aig_Man_t * pAig )
+{
+ bool header_dumped = false;
+ int num_orig_latches = Abc_NtkLatchNum(pNtk);
+ char **pNames = ALLOC( char *, num_orig_latches );
+ bool *p_irrelevant = ALLOC( bool, num_orig_latches );
+ char * pFlopName, * pReprName;
+ Aig_Obj_t * pFlop, * pRepr;
+ Abc_Obj_t * pNtkFlop;
+ int repr_idx;
+ int i;
+
+ Abc_NtkForEachLatch( pNtk, pNtkFlop, i )
+ {
+ char *temp_name = Abc_ObjName( Abc_ObjFanout0(pNtkFlop) );
+ pNames[i] = ALLOC( char , strlen(temp_name)+1);
+ strcpy(pNames[i], temp_name);
+ }
+ i = 0;
+
+ Aig_ManSetPioNumbers( pAig );
+ Saig_ManForEachLo( pAig, pFlop, i )
+ {
+ p_irrelevant[i] = false;
+
+ pFlopName = pNames[i];
+
+ pRepr = Aig_ObjRepr(pAig, pFlop);
+
+ if ( pRepr == NULL )
+ {
+ // printf("Nothing equivalent to flop %s\n", pFlopName);
+ p_irrelevant[i] = true;
+ continue;
+ }
+
+ if (!header_dumped)
+ {
+ printf("Here are the flop equivalences:\n");
+ header_dumped = true;
+ }
+
+ // pRepr is representative of the equivalence class, to which pFlop belongs
+ if ( Aig_ObjIsConst1(pRepr) )
+ {
+ printf( "Original flop %s is proved equivalent to constant.\n", pFlopName );
+ // printf( "Original flop # %d is proved equivalent to constant.\n", i );
+ continue;
+ }
+
+ assert( Saig_ObjIsLo( pAig, pRepr ) );
+ repr_idx = Aig_ObjPioNum(pRepr) - Saig_ManPiNum(pAig);
+ pReprName = pNames[repr_idx];
+ printf( "Original flop %s is proved equivalent to flop %s.\n", pFlopName, pReprName );
+ // printf( "Original flop # %d is proved equivalent to flop # %d.\n", i, repr_idx );
+ }
+
+ header_dumped = false;
+ for (i=0; i<num_orig_latches; ++i)
+ {
+ if (p_irrelevant[i])
+ {
+ if (!header_dumped)
+ {
+ printf("The following flops have been deemed irrelevant:\n");
+ header_dumped = true;
+ }
+ printf("%s ", pNames[i]);
+ }
+
+ FREE(pNames[i]);
+ }
+ if (header_dumped)
+ printf("\n");
+
+ FREE(pNames);
+ FREE(p_irrelevant);
+}
+
+/**Function*************************************************************
+
Synopsis [Gives the current ABC network to AIG manager for processing.]
Description []
@@ -1259,7 +1349,11 @@ Abc_Ntk_t * Abc_NtkDarSeqSweep2( Abc_Ntk_t * pNtk, Ssw_Pars_t * pPars )
return NULL;
pMan = Ssw_SignalCorrespondence( pTemp = pMan, pPars );
- Aig_ManStop( pTemp );
+
+ if ( pPars->fFlopVerbose )
+ Abc_NtkPrintLatchEquivClasses(pNtk, pTemp);
+
+ Aig_ManStop( pTemp );
if ( pMan == NULL )
return NULL;
@@ -1474,6 +1568,47 @@ PRT( "Time", clock() - clk );
SeeAlso []
***********************************************************************/
+int Abc_NtkDarDemiter( Abc_Ntk_t * pNtk )
+{
+ Aig_Man_t * pMan, * pPart0, * pPart1, * pMiter;
+ // derive the AIG manager
+ pMan = Abc_NtkToDar( pNtk, 0, 1 );
+ if ( pMan == NULL )
+ {
+ printf( "Converting network into AIG has failed.\n" );
+ return 0;
+ }
+ if ( !Saig_ManDemiterSimple( pMan, &pPart0, &pPart1 ) )
+ {
+ printf( "Demitering has failed.\n" );
+ return 0;
+ }
+ Aig_ManDumpBlif( pPart0, "part0.blif", NULL, NULL );
+ Aig_ManDumpBlif( pPart1, "part1.blif", NULL, NULL );
+ printf( "The result of demitering is written into files \"%s\" and \"%s\".\n", "part0.blif", "part1.blif" );
+ // create two-level miter
+ pMiter = Saig_ManCreateMiterTwo( pPart0, pPart1, 2 );
+ Aig_ManDumpBlif( pMiter, "miter01.blif", NULL, NULL );
+ Aig_ManStop( pMiter );
+ printf( "The new miter is written into file \"%s\".\n", "miter01.blif" );
+
+ Aig_ManStop( pPart0 );
+ Aig_ManStop( pPart1 );
+ Aig_ManStop( pMan );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Gives the current ABC network to AIG manager for processing.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_NtkDarProve( Abc_Ntk_t * pNtk, Fra_Sec_t * pSecPar )
{
Aig_Man_t * pMan;
@@ -2457,9 +2592,9 @@ void Abc_NtkDarReach( Abc_Ntk_t * pNtk, int nBddMax, int nIterMax, int fPartitio
***********************************************************************/
void Abc_NtkDarTest( Abc_Ntk_t * pNtk )
{
- extern Aig_Man_t * Ssw_SignalCorrespondeceTestPairs( Aig_Man_t * pAig );
+// extern Aig_Man_t * Ssw_SignalCorrespondeceTestPairs( Aig_Man_t * pAig );
- Aig_Man_t * pMan, * pTemp;
+ Aig_Man_t * pMan;//, * pTemp;
assert( Abc_NtkIsStrash(pNtk) );
pMan = Abc_NtkToDar( pNtk, 0, 1 );
if ( pMan == NULL )
@@ -2472,9 +2607,13 @@ Aig_ManStop( pMan );
pMan = Saig_ManReadBlif( "_temp_.blif" );
Aig_ManPrintStats( pMan );
*/
+/*
Aig_ManSetRegNum( pMan, pMan->nRegs );
pTemp = Ssw_SignalCorrespondeceTestPairs( pMan );
Aig_ManStop( pTemp );
+*/
+ Ssw_SecSpecialMiter( pMan, 0 );
+
Aig_ManStop( pMan );
}
diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c
index 75aa0064..4e0a4c95 100644
--- a/src/base/cmd/cmd.c
+++ b/src/base/cmd/cmd.c
@@ -50,6 +50,7 @@ static int CmdCommandEmpty ( Abc_Frame_t * pAbc, int argc, char ** argv
static int CmdCommandLs ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandScrGen ( Abc_Frame_t * pAbc, int argc, char ** argv );
#endif
+static int CmdCommandVersion ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int CmdCommandCapo ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -68,7 +69,7 @@ static int CmdCommandCapo ( Abc_Frame_t * pAbc, int argc, char ** argv
******************************************************************************/
void Cmd_Init( Abc_Frame_t * pAbc )
-{
+{
pAbc->tCommands = st_init_table(strcmp, st_strhash);
pAbc->tAliases = st_init_table(strcmp, st_strhash);
pAbc->tFlags = st_init_table(strcmp, st_strhash);
@@ -91,6 +92,7 @@ void Cmd_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Basic", "ls", CmdCommandLs, 0 );
Cmd_CommandAdd( pAbc, "Basic", "scrgen", CmdCommandScrGen, 0 );
#endif
+ Cmd_CommandAdd( pAbc, "Basic", "version", CmdCommandVersion, 0);
Cmd_CommandAdd( pAbc, "Various", "sis", CmdCommandSis, 1);
Cmd_CommandAdd( pAbc, "Various", "mvsis", CmdCommandMvsis, 1);
@@ -1910,6 +1912,22 @@ usage:
return 1; // error exit
}
+/**Function********************************************************************
+
+ Synopsis [Print the version string.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+******************************************************************************/
+int CmdCommandVersion( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ printf("%s\n", Abc_UtilsGetVersion(pAbc));
+ return 0;
+}
////////////////////////////////////////////////////////////////////////
diff --git a/src/base/cmd/cmd.h b/src/base/cmd/cmd.h
index 030b77e8..9d0b8703 100644
--- a/src/base/cmd/cmd.h
+++ b/src/base/cmd/cmd.h
@@ -40,6 +40,17 @@ extern "C" {
typedef struct MvCommand Abc_Command; // one command
typedef struct MvAlias Abc_Alias; // one alias
+#ifdef WIN32
+#define DLLEXPORT __declspec(dllexport)
+#define DLLIMPORT __declspec(dllimport)
+#else /* defined(WIN32) */
+#define DLLIMPORT
+#endif /* defined(WIN32) */
+
+#ifndef ABC_DLL
+#define ABC_DLL DLLIMPORT
+#endif
+
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -53,7 +64,7 @@ extern void Cmd_Init();
extern void Cmd_End();
/*=== cmdApi.c ========================================================*/
extern void Cmd_CommandAdd( Abc_Frame_t * pAbc, char * sGroup, char * sName, void * pFunc, int fChanges );
-extern int Cmd_CommandExecute( Abc_Frame_t * pAbc, char * sCommand );
+extern ABC_DLL int Cmd_CommandExecute( Abc_Frame_t * pAbc, char * sCommand );
/*=== cmdFlag.c ========================================================*/
extern char * Cmd_FlagReadByName( Abc_Frame_t * pAbc, char * flag );
extern void Cmd_FlagDeleteByName( Abc_Frame_t * pAbc, char * key );
diff --git a/src/base/io/io.c b/src/base/io/io.c
index 6d7948ab..6f326a27 100644
--- a/src/base/io/io.c
+++ b/src/base/io/io.c
@@ -1710,30 +1710,7 @@ int IoCommandWriteCounter( Abc_Frame_t * pAbc, int argc, char **argv )
}
// write the counter-example into the file
- if ( pNtk->pModel )
- {
- Abc_Obj_t * pObj;
- FILE * pFile = fopen( pFileName, "w" );
- int i;
- if ( pFile == NULL )
- {
- fprintf( stdout, "IoCommandWriteCounter(): Cannot open the output file \"%s\".\n", pFileName );
- return 1;
- }
- if ( fNames )
- {
- Abc_NtkForEachPi( pNtk, pObj, i )
- fprintf( pFile, "%s=%c ", Abc_ObjName(pObj), '0'+(pNtk->pModel[i]==1) );
- }
- else
- {
- Abc_NtkForEachPi( pNtk, pObj, i )
- fprintf( pFile, "%c", '0'+(pNtk->pModel[i]==1) );
- }
- fprintf( pFile, "\n" );
- fclose( pFile );
- }
- else
+ if ( pNtk->pSeqModel )
{
Fra_Cex_t * pCex = pNtk->pSeqModel;
Abc_Obj_t * pObj;
@@ -1771,6 +1748,29 @@ int IoCommandWriteCounter( Abc_Frame_t * pAbc, int argc, char **argv )
fprintf( pFile, "\n" );
fclose( pFile );
}
+ else
+ {
+ Abc_Obj_t * pObj;
+ FILE * pFile = fopen( pFileName, "w" );
+ int i;
+ if ( pFile == NULL )
+ {
+ fprintf( stdout, "IoCommandWriteCounter(): Cannot open the output file \"%s\".\n", pFileName );
+ return 1;
+ }
+ if ( fNames )
+ {
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ fprintf( pFile, "%s=%c ", Abc_ObjName(pObj), '0'+(pNtk->pModel[i]==1) );
+ }
+ else
+ {
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ fprintf( pFile, "%c", '0'+(pNtk->pModel[i]==1) );
+ }
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+ }
return 0;
diff --git a/src/base/main/mainUtils.c b/src/base/main/mainUtils.c
index d69055a4..46469490 100644
--- a/src/base/main/mainUtils.c
+++ b/src/base/main/mainUtils.c
@@ -200,14 +200,26 @@ void Abc_UtilsSource( Abc_Frame_t * pAbc )
if ( sPath1 && sPath2 ) {
/* ~/.rc == .rc : Source the file only once */
- (void) Cmd_CommandExecute(pAbc, "source -s ~/.abc.rc");
+ char *tmp_cmd = ALLOC(char, strlen(sPath1)+12);
+ (void) sprintf(tmp_cmd, "source -s %s", sPath1);
+ // (void) Cmd_CommandExecute(pAbc, "source -s ~/.abc.rc");
+ (void) Cmd_CommandExecute(pAbc, tmp_cmd);
+ FREE(tmp_cmd);
}
else {
if (sPath1) {
- (void) Cmd_CommandExecute(pAbc, "source -s ~/.abc.rc");
+ char *tmp_cmd = ALLOC(char, strlen(sPath1)+12);
+ (void) sprintf(tmp_cmd, "source -s %s", sPath1);
+ // (void) Cmd_CommandExecute(pAbc, "source -s ~/.abc.rc");
+ (void) Cmd_CommandExecute(pAbc, tmp_cmd);
+ FREE(tmp_cmd);
}
if (sPath2) {
- (void) Cmd_CommandExecute(pAbc, "source -s .abc.rc");
+ char *tmp_cmd = ALLOC(char, strlen(sPath2)+12);
+ (void) sprintf(tmp_cmd, "source -s %s", sPath2);
+ // (void) Cmd_CommandExecute(pAbc, "source -s .abc.rc");
+ (void) Cmd_CommandExecute(pAbc, tmp_cmd);
+ FREE(tmp_cmd);
}
}
if ( sPath1 ) FREE(sPath1);
diff --git a/src/misc/extra/extra.h b/src/misc/extra/extra.h
index d63ed5d3..beb5a4d0 100644
--- a/src/misc/extra/extra.h
+++ b/src/misc/extra/extra.h
@@ -76,6 +76,18 @@ extern "C" {
/* Macro declarations */
/*---------------------------------------------------------------------------*/
+#ifdef WIN32
+#define DLLEXPORT __declspec(dllexport)
+#define DLLIMPORT __declspec(dllimport)
+#else /* defined(WIN32) */
+#define DLLIMPORT
+#endif /* defined(WIN32) */
+
+#ifndef ABC_DLL
+#define ABC_DLL DLLIMPORT
+#endif
+
+
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
@@ -633,19 +645,19 @@ extern unsigned Extra_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux
#endif
-extern long Extra_CpuTime();
-extern double Extra_CpuTimeDouble();
-extern int Extra_GetSoftDataLimit();
-extern void Extra_UtilGetoptReset();
-extern int Extra_UtilGetopt( int argc, char *argv[], char *optstring );
-extern char * Extra_UtilPrintTime( long t );
-extern char * Extra_UtilStrsav( char *s );
-extern char * Extra_UtilTildeExpand( char *fname );
-extern char * Extra_UtilFileSearch( char *file, char *path, char *mode );
-extern void (*Extra_UtilMMoutOfMemory)();
+extern long Extra_CpuTime();
+extern double Extra_CpuTimeDouble();
+extern int Extra_GetSoftDataLimit();
+extern ABC_DLL void Extra_UtilGetoptReset();
+extern int Extra_UtilGetopt( int argc, char *argv[], char *optstring );
+extern char * Extra_UtilPrintTime( long t );
+extern char * Extra_UtilStrsav( char *s );
+extern char * Extra_UtilTildeExpand( char *fname );
+extern char * Extra_UtilFileSearch( char *file, char *path, char *mode );
+extern void (*Extra_UtilMMoutOfMemory)();
-extern char * globalUtilOptarg;
-extern int globalUtilOptind;
+extern char * globalUtilOptarg;
+extern int globalUtilOptind;
/**AutomaticEnd***************************************************************/
diff --git a/src/sat/bsat/satChecker.c b/src/sat/bsat/satChecker.c
new file mode 100644
index 00000000..1488fe2f
--- /dev/null
+++ b/src/sat/bsat/satChecker.c
@@ -0,0 +1,187 @@
+/**CFile****************************************************************
+
+ FileName [satChecker.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT sat_solver.]
+
+ Synopsis [Resolution proof checker.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: satChecker.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
+
+***********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include "vec.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sat_PrintClause( Vec_Vec_t * vClauses, int Clause )
+{
+ Vec_Int_t * vClause;
+ int i, Entry;
+ printf( "Clause %d: {", Clause );
+ vClause = Vec_VecEntry( vClauses, Clause );
+ Vec_IntForEachEntry( vClause, Entry, i )
+ printf( " %d", Entry );
+ printf( " }\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Sat_ProofResolve( Vec_Vec_t * vClauses, int Result, int Clause1, int Clause2 )
+{
+ Vec_Int_t * vResult = Vec_VecEntry( vClauses, Result );
+ Vec_Int_t * vClause1 = Vec_VecEntry( vClauses, Clause1 );
+ Vec_Int_t * vClause2 = Vec_VecEntry( vClauses, Clause2 );
+ int Entry1, Entry2, ResVar;
+ int i, j, Counter = 0;
+
+ Vec_IntForEachEntry( vClause1, Entry1, i )
+ Vec_IntForEachEntry( vClause2, Entry2, j )
+ if ( Entry1 == -Entry2 )
+ {
+ ResVar = Entry1;
+ Counter++;
+ }
+ if ( Counter != 1 )
+ {
+ printf( "Error: Clause %d = Resolve(%d, %d): The number of pivot vars is %d.\n",
+ Result, Clause1, Clause2, Counter );
+ Sat_PrintClause( vClauses, Clause1 );
+ Sat_PrintClause( vClauses, Clause2 );
+ return 0;
+ }
+ // create new clause
+ assert( Vec_IntSize(vResult) == 0 );
+ Vec_IntForEachEntry( vClause1, Entry1, i )
+ if ( Entry1 != ResVar && Entry1 != -ResVar )
+ Vec_IntPushUnique( vResult, Entry1 );
+ assert( Vec_IntSize(vResult) + 1 == Vec_IntSize(vClause1) );
+ Vec_IntForEachEntry( vClause2, Entry2, i )
+ if ( Entry2 != ResVar && Entry2 != -ResVar )
+ Vec_IntPushUnique( vResult, Entry2 );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sat_ProofChecker( char * pFileName )
+{
+ FILE * pFile;
+ Vec_Vec_t * vClauses;
+ int c, i, Num, RetValue, Counter, Counter2, Clause1, Clause2;
+ // open the file
+ pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ return;
+ // count the number of clauses
+ Counter = Counter2 = 0;
+ while ( (c = fgetc(pFile)) != EOF )
+ {
+ Counter += (c == '\n');
+ Counter2 += (c == '*');
+ }
+ vClauses = Vec_VecStart( Counter+1 );
+ printf( "The proof contains %d roots and %d resolution steps.\n", Counter-Counter2, Counter2 );
+ // read the clauses
+ rewind( pFile );
+ for ( i = 1 ; ; i++ )
+ {
+ RetValue = fscanf( pFile, "%d", &Num );
+ if ( RetValue != 1 )
+ break;
+ assert( Num == i );
+ while ( (c = fgetc( pFile )) == ' ' );
+ if ( c == '*' )
+ {
+ RetValue = fscanf( pFile, "%d %d", &Clause1, &Clause2 );
+ assert( RetValue == 2 );
+ RetValue = fscanf( pFile, "%d", &Num );
+ assert( RetValue == 1 );
+ assert( Num == 0 );
+ if ( !Sat_ProofResolve( vClauses, i, Clause1, Clause2 ) )
+ {
+ printf( "Error detected in the resolution proof.\n" );
+ Vec_VecFree( vClauses );
+ fclose( pFile );
+ return;
+ }
+ }
+ else
+ {
+ ungetc( c, pFile );
+ while ( 1 )
+ {
+ RetValue = fscanf( pFile, "%d", &Num );
+ assert( RetValue == 1 );
+ if ( Num == 0 )
+ break;
+ Vec_VecPush( vClauses, i, (void *)Num );
+ }
+ RetValue = fscanf( pFile, "%d", &Num );
+ assert( RetValue == 1 );
+ assert( Num == 0 );
+ }
+ }
+ assert( i-1 == Counter );
+ if ( Vec_IntSize( Vec_VecEntry(vClauses, Counter) ) != 0 )
+ printf( "The last clause is not empty.\n" );
+ else
+ printf( "The empty clause is derived.\n" );
+ Vec_VecFree( vClauses );
+ fclose( pFile );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/sat/bsat/satInterA.c b/src/sat/bsat/satInterA.c
index 57628989..5edc5b67 100644
--- a/src/sat/bsat/satInterA.c
+++ b/src/sat/bsat/satInterA.c
@@ -701,6 +701,10 @@ p->timeTrace += clock() - clk;
// Inta_ManPrintInterOne( p, pFinal );
}
Inta_ManProofSet( p, pFinal, p->Counter );
+ // make sure the same proof ID is not asssigned to two consecutive clauses
+ assert( p->pProofNums[pFinal->Id-1] != p->Counter );
+// if ( p->pProofNums[pFinal->Id] == p->pProofNums[pFinal->Id-1] )
+// p->pProofNums[pFinal->Id] = p->pProofNums[pConflict->Id];
return p->Counter;
}
@@ -748,6 +752,27 @@ int Inta_ManProofRecordOne( Inta_Man_t * p, Sto_Cls_t * pClause )
{
assert( 0 ); // cannot prove
return 0;
+ }
+
+ // skip the clause if it is weaker or the same as the conflict clause
+ if ( pClause->nLits >= pConflict->nLits )
+ {
+ // check if every literal of conflict clause can be found in the given clause
+ int j;
+ for ( i = 0; i < (int)pConflict->nLits; i++ )
+ {
+ for ( j = 0; j < (int)pClause->nLits; j++ )
+ if ( pConflict->pLits[i] == pClause->pLits[j] )
+ break;
+ if ( j == (int)pClause->nLits ) // literal pConflict->pLits[i] is not found
+ break;
+ }
+ if ( i == (int)pConflict->nLits ) // all lits are found
+ {
+ // undo to the root level
+ Inta_ManCancelUntil( p, p->nRootSize );
+ return 1;
+ }
}
// construct the proof
@@ -973,6 +998,7 @@ void * Inta_ManInterpolate( Inta_Man_t * p, Sto_Man_t * pCnf, void * vVarsAB, in
if ( p->fProofWrite )
{
fclose( p->pFile );
+// Sat_ProofChecker( "proof.cnf_" );
p->pFile = NULL;
}
diff --git a/src/sat/bsat/satInterA_mod.c b/src/sat/bsat/satInterA_mod.c
new file mode 100644
index 00000000..faf396a6
--- /dev/null
+++ b/src/sat/bsat/satInterA_mod.c
@@ -0,0 +1,1104 @@
+/**CFile****************************************************************
+
+ FileName [satInter.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT sat_solver.]
+
+ Synopsis [Interpolation package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: satInter.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
+
+***********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include "satStore.h"
+#include "aig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// variable assignments
+static const lit LIT_UNDEF = 0xffffffff;
+
+// interpolation manager
+struct Inta_Man_t_
+{
+ // clauses of the problems
+ Sto_Man_t * pCnf; // the set of CNF clauses for A and B
+ Vec_Int_t * vVarsAB; // the array of global variables
+ // various parameters
+ int fVerbose; // verbosiness flag
+ int fProofVerif; // verifies the proof
+ int fProofWrite; // writes the proof file
+ int nVarsAlloc; // the allocated size of var arrays
+ int nClosAlloc; // the allocated size of clause arrays
+ // internal BCP
+ int nRootSize; // the number of root level assignments
+ int nTrailSize; // the number of assignments made
+ lit * pTrail; // chronological order of assignments (size nVars)
+ lit * pAssigns; // assignments by variable (size nVars)
+ char * pSeens; // temporary mark (size nVars)
+ Sto_Cls_t ** pReasons; // reasons for each assignment (size nVars)
+ Sto_Cls_t ** pWatches; // watched clauses for each literal (size 2*nVars)
+ // interpolation data
+ Aig_Man_t * pAig; // the AIG manager for recording the interpolant
+ int * pVarTypes; // variable type (size nVars) [1=A, 0=B, <0=AB]
+ Aig_Obj_t ** pInters; // storage for interpolants as truth tables (size nClauses)
+ int nIntersAlloc; // the allocated size of truth table array
+ // proof recording
+ int Counter; // counter of resolved clauses
+ int * pProofNums; // the proof numbers for each clause (size nClauses)
+ FILE * pFile; // the file for proof recording
+ // internal verification
+ lit * pResLits; // the literals of the resolvent
+ int nResLits; // the number of literals of the resolvent
+ int nResLitsAlloc;// the number of literals of the resolvent
+ // runtime stats
+ int timeBcp; // the runtime for BCP
+ int timeTrace; // the runtime of trace construction
+ int timeTotal; // the total runtime of interpolation
+};
+
+// procedure to get hold of the clauses' truth table
+static inline Aig_Obj_t ** Inta_ManAigRead( Inta_Man_t * pMan, Sto_Cls_t * pCls ) { return pMan->pInters + pCls->Id; }
+static inline void Inta_ManAigClear( Inta_Man_t * pMan, Aig_Obj_t ** p ) { *p = Aig_ManConst0(pMan->pAig); }
+static inline void Inta_ManAigFill( Inta_Man_t * pMan, Aig_Obj_t ** p ) { *p = Aig_ManConst1(pMan->pAig); }
+static inline void Inta_ManAigCopy( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q ) { *p = *q; }
+static inline void Inta_ManAigAnd( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q ) { *p = Aig_And(pMan->pAig, *p, *q); }
+static inline void Inta_ManAigOr( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q ) { *p = Aig_Or(pMan->pAig, *p, *q); }
+static inline void Inta_ManAigOrNot( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q ) { *p = Aig_Or(pMan->pAig, *p, Aig_Not(*q)); }
+static inline void Inta_ManAigOrVar( Inta_Man_t * pMan, Aig_Obj_t ** p, int v ) { *p = Aig_Or(pMan->pAig, *p, Aig_IthVar(pMan->pAig, v)); }
+static inline void Inta_ManAigOrNotVar( Inta_Man_t * pMan, Aig_Obj_t ** p, int v ) { *p = Aig_Or(pMan->pAig, *p, Aig_Not(Aig_IthVar(pMan->pAig, v))); }
+
+// reading/writing the proof for a clause
+static inline int Inta_ManProofGet( Inta_Man_t * p, Sto_Cls_t * pCls ) { return p->pProofNums[pCls->Id]; }
+static inline void Inta_ManProofSet( Inta_Man_t * p, Sto_Cls_t * pCls, int n ) {
+ p->pProofNums[pCls->Id] = n;
+ if ( pCls->Id == 5552 || pCls->Id == 5553 )
+ {
+ int x = 0;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocate proof manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Inta_Man_t * Inta_ManAlloc()
+{
+ Inta_Man_t * p;
+ // allocate the manager
+ p = (Inta_Man_t *)malloc( sizeof(Inta_Man_t) );
+ memset( p, 0, sizeof(Inta_Man_t) );
+ // verification
+ p->nResLitsAlloc = (1<<16);
+ p->pResLits = malloc( sizeof(lit) * p->nResLitsAlloc );
+ // parameters
+ p->fProofWrite = 1;
+ p->fProofVerif = 1;
+
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Count common variables in the clauses of A and B.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Inta_ManGlobalVars( Inta_Man_t * p )
+{
+ Sto_Cls_t * pClause;
+ int LargeNum = -100000000;
+ int Var, nVarsAB, v;
+
+ // mark the variable encountered in the clauses of A
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ {
+ if ( !pClause->fA )
+ break;
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ p->pVarTypes[lit_var(pClause->pLits[v])] = 1;
+ }
+
+ // check variables that appear in clauses of B
+ nVarsAB = 0;
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ {
+ if ( pClause->fA )
+ continue;
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ {
+ Var = lit_var(pClause->pLits[v]);
+ if ( p->pVarTypes[Var] == 1 ) // var of A
+ {
+ // change it into a global variable
+ nVarsAB++;
+ p->pVarTypes[Var] = LargeNum;
+ }
+ }
+ }
+ assert( nVarsAB <= Vec_IntSize(p->vVarsAB) );
+
+ // order global variables
+ nVarsAB = 0;
+ Vec_IntForEachEntry( p->vVarsAB, Var, v )
+ p->pVarTypes[Var] = -(1+nVarsAB++);
+
+ // check that there is no extra global variables
+ for ( v = 0; v < p->pCnf->nVars; v++ )
+ assert( p->pVarTypes[v] != LargeNum );
+ return nVarsAB;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resize proof manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManResize( Inta_Man_t * p )
+{
+ // check if resizing is needed
+ if ( p->nVarsAlloc < p->pCnf->nVars )
+ {
+ // find the new size
+ if ( p->nVarsAlloc == 0 )
+ p->nVarsAlloc = 1;
+ while ( p->nVarsAlloc < p->pCnf->nVars )
+ p->nVarsAlloc *= 2;
+ // resize the arrays
+ p->pTrail = (lit *) realloc( p->pTrail, sizeof(lit) * p->nVarsAlloc );
+ p->pAssigns = (lit *) realloc( p->pAssigns, sizeof(lit) * p->nVarsAlloc );
+ p->pSeens = (char *) realloc( p->pSeens, sizeof(char) * p->nVarsAlloc );
+ p->pVarTypes = (int *) realloc( p->pVarTypes, sizeof(int) * p->nVarsAlloc );
+ p->pReasons = (Sto_Cls_t **)realloc( p->pReasons, sizeof(Sto_Cls_t *) * p->nVarsAlloc );
+ p->pWatches = (Sto_Cls_t **)realloc( p->pWatches, sizeof(Sto_Cls_t *) * p->nVarsAlloc*2 );
+ }
+
+ // clean the free space
+ memset( p->pAssigns , 0xff, sizeof(lit) * p->pCnf->nVars );
+ memset( p->pSeens , 0, sizeof(char) * p->pCnf->nVars );
+ memset( p->pVarTypes, 0, sizeof(int) * p->pCnf->nVars );
+ memset( p->pReasons , 0, sizeof(Sto_Cls_t *) * p->pCnf->nVars );
+ memset( p->pWatches , 0, sizeof(Sto_Cls_t *) * p->pCnf->nVars*2 );
+
+ // compute the number of common variables
+ Inta_ManGlobalVars( p );
+
+ // check if resizing of clauses is needed
+ if ( p->nClosAlloc < p->pCnf->nClauses )
+ {
+ // find the new size
+ if ( p->nClosAlloc == 0 )
+ p->nClosAlloc = 1;
+ while ( p->nClosAlloc < p->pCnf->nClauses )
+ p->nClosAlloc *= 2;
+ // resize the arrays
+ p->pProofNums = (int *) realloc( p->pProofNums, sizeof(int) * p->nClosAlloc );
+ }
+ memset( p->pProofNums, 0, sizeof(int) * p->pCnf->nClauses );
+
+ // check if resizing of truth tables is needed
+ if ( p->nIntersAlloc < p->pCnf->nClauses )
+ {
+ p->nIntersAlloc = p->pCnf->nClauses;
+ p->pInters = (Aig_Obj_t **) realloc( p->pInters, sizeof(Aig_Obj_t *) * p->nIntersAlloc );
+ }
+ memset( p->pInters, 0, sizeof(Aig_Obj_t *) * p->pCnf->nClauses );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deallocate proof manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManFree( Inta_Man_t * p )
+{
+/*
+ printf( "Runtime stats:\n" );
+PRT( "BCP ", p->timeBcp );
+PRT( "Trace ", p->timeTrace );
+PRT( "TOTAL ", p->timeTotal );
+*/
+ free( p->pInters );
+ free( p->pProofNums );
+ free( p->pTrail );
+ free( p->pAssigns );
+ free( p->pSeens );
+ free( p->pVarTypes );
+ free( p->pReasons );
+ free( p->pWatches );
+ free( p->pResLits );
+ free( p );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints the clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManPrintClause( Inta_Man_t * p, Sto_Cls_t * pClause )
+{
+ int i;
+ printf( "Clause ID = %d. Proof = %d. {", pClause->Id, Inta_ManProofGet(p, pClause) );
+ for ( i = 0; i < (int)pClause->nLits; i++ )
+ printf( " %d", pClause->pLits[i] );
+ printf( " }\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the resolvent.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManPrintResolvent( lit * pResLits, int nResLits )
+{
+ int i;
+ printf( "Resolvent: {" );
+ for ( i = 0; i < nResLits; i++ )
+ // Yu Hu
+ // printf( " %d", pResLits[i] );
+ printf( " %d", lit_print(pResLits[i]) );
+ printf( " }\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the interpolant for one clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManPrintInterOne( Inta_Man_t * p, Sto_Cls_t * pClause )
+{
+ printf( "Clause %2d : ", pClause->Id );
+// Extra_PrintBinary___( stdout, Inta_ManAigRead(p, pClause), (1 << p->nVarsAB) );
+ printf( "\n" );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Adds one clause to the watcher list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Inta_ManWatchClause( Inta_Man_t * p, Sto_Cls_t * pClause, lit Lit )
+{
+ assert( lit_check(Lit, p->pCnf->nVars) );
+ if ( pClause->pLits[0] == Lit )
+ pClause->pNext0 = p->pWatches[lit_neg(Lit)];
+ else
+ {
+ assert( pClause->pLits[1] == Lit );
+ pClause->pNext1 = p->pWatches[lit_neg(Lit)];
+ }
+ p->pWatches[lit_neg(Lit)] = pClause;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Records implication.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Inta_ManEnqueue( Inta_Man_t * p, lit Lit, Sto_Cls_t * pReason )
+{
+ int Var = lit_var(Lit);
+ if ( p->pAssigns[Var] != LIT_UNDEF )
+ return p->pAssigns[Var] == Lit;
+ p->pAssigns[Var] = Lit;
+ p->pReasons[Var] = pReason;
+ p->pTrail[p->nTrailSize++] = Lit;
+//printf( "assigning var %d value %d\n", Var, !lit_sign(Lit) );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Records implication.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Inta_ManCancelUntil( Inta_Man_t * p, int Level )
+{
+ lit Lit;
+ int i, Var;
+ for ( i = p->nTrailSize - 1; i >= Level; i-- )
+ {
+ Lit = p->pTrail[i];
+ Var = lit_var( Lit );
+ p->pReasons[Var] = NULL;
+ p->pAssigns[Var] = LIT_UNDEF;
+//printf( "cancelling var %d\n", Var );
+ }
+ p->nTrailSize = Level;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate one assignment.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Sto_Cls_t * Inta_ManPropagateOne( Inta_Man_t * p, lit Lit )
+{
+ Sto_Cls_t ** ppPrev, * pCur, * pTemp;
+ lit LitF = lit_neg(Lit);
+ int i;
+ // iterate through the literals
+ ppPrev = p->pWatches + Lit;
+ for ( pCur = p->pWatches[Lit]; pCur; pCur = *ppPrev )
+ {
+ // make sure the false literal is in the second literal of the clause
+ if ( pCur->pLits[0] == LitF )
+ {
+ pCur->pLits[0] = pCur->pLits[1];
+ pCur->pLits[1] = LitF;
+ pTemp = pCur->pNext0;
+ pCur->pNext0 = pCur->pNext1;
+ pCur->pNext1 = pTemp;
+ }
+ assert( pCur->pLits[1] == LitF );
+
+ // if the first literal is true, the clause is satisfied
+ if ( pCur->pLits[0] == p->pAssigns[lit_var(pCur->pLits[0])] )
+ {
+ ppPrev = &pCur->pNext1;
+ continue;
+ }
+
+ // look for a new literal to watch
+ for ( i = 2; i < (int)pCur->nLits; i++ )
+ {
+ // skip the case when the literal is false
+ if ( lit_neg(pCur->pLits[i]) == p->pAssigns[lit_var(pCur->pLits[i])] )
+ continue;
+ // the literal is either true or unassigned - watch it
+ pCur->pLits[1] = pCur->pLits[i];
+ pCur->pLits[i] = LitF;
+ // remove this clause from the watch list of Lit
+ *ppPrev = pCur->pNext1;
+ // add this clause to the watch list of pCur->pLits[i] (now it is pCur->pLits[1])
+ Inta_ManWatchClause( p, pCur, pCur->pLits[1] );
+ break;
+ }
+ if ( i < (int)pCur->nLits ) // found new watch
+ continue;
+
+ // clause is unit - enqueue new implication
+ if ( Inta_ManEnqueue(p, pCur->pLits[0], pCur) )
+ {
+ ppPrev = &pCur->pNext1;
+ continue;
+ }
+
+ // conflict detected - return the conflict clause
+ return pCur;
+ }
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate the current assignments.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Sto_Cls_t * Inta_ManPropagate( Inta_Man_t * p, int Start )
+{
+ Sto_Cls_t * pClause;
+ int i;
+ int clk = clock();
+ for ( i = Start; i < p->nTrailSize; i++ )
+ {
+ pClause = Inta_ManPropagateOne( p, p->pTrail[i] );
+ if ( pClause )
+ {
+p->timeBcp += clock() - clk;
+ return pClause;
+ }
+ }
+p->timeBcp += clock() - clk;
+ return NULL;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes one root clause into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManProofWriteOne( Inta_Man_t * p, Sto_Cls_t * pClause )
+{
+ Inta_ManProofSet( p, pClause, ++p->Counter );
+
+ if ( p->fProofWrite )
+ {
+ int v;
+ fprintf( p->pFile, "%d", Inta_ManProofGet(p, pClause) );
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ fprintf( p->pFile, " %d", lit_print(pClause->pLits[v]) );
+ fprintf( p->pFile, " 0 0\n" );
+ }
+}
+
+// Yu Hu
+void Inta_ManPrintClauseEx( lit * pResLits, int nResLits )
+{
+ int i;
+ printf( " {" );
+ for ( i = 0; i < nResLits; i++ )
+ printf( " %d", lit_print(pResLits[i]) );
+ printf( " }\n" );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Traces the proof for one clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pFinal )
+{
+ Sto_Cls_t * pReason;
+ int i, v, Var, PrevId;
+ int fPrint = 1; // Yu Hu
+ int clk = clock();
+
+ // collect resolvent literals
+ if ( p->fProofVerif )
+ {
+ assert( (int)pConflict->nLits <= p->nResLitsAlloc );
+ memcpy( p->pResLits, pConflict->pLits, sizeof(lit) * pConflict->nLits );
+ p->nResLits = pConflict->nLits;
+ }
+
+ // mark all the variables in the conflict as seen
+ for ( v = 0; v < (int)pConflict->nLits; v++ )
+ p->pSeens[lit_var(pConflict->pLits[v])] = 1;
+
+ // start the anticedents
+// pFinal->pAntis = Vec_PtrAlloc( 32 );
+// Vec_PtrPush( pFinal->pAntis, pConflict );
+
+ if ( p->pCnf->nClausesA )
+ Inta_ManAigCopy( p, Inta_ManAigRead(p, pFinal), Inta_ManAigRead(p, pConflict) );
+
+ // follow the trail backwards
+ PrevId = Inta_ManProofGet(p, pConflict);
+ for ( i = p->nTrailSize - 1; i >= 0; i-- )
+ {
+ // skip literals that are not involved
+ Var = lit_var(p->pTrail[i]);
+ if ( !p->pSeens[Var] )
+ continue;
+ p->pSeens[Var] = 0;
+
+ // skip literals of the resulting clause
+ pReason = p->pReasons[Var];
+ if ( pReason == NULL )
+ continue;
+ assert( p->pTrail[i] == pReason->pLits[0] );
+
+ // add the variables to seen
+ for ( v = 1; v < (int)pReason->nLits; v++ )
+ p->pSeens[lit_var(pReason->pLits[v])] = 1;
+
+ // record the reason clause
+ assert( Inta_ManProofGet(p, pReason) > 0 );
+ p->Counter++;
+ if ( p->fProofWrite && p->Counter >= 8370 && p->Counter <= 8380 ) {
+ fprintf( p->pFile, "%d * %d %d 0\n", p->Counter, PrevId, Inta_ManProofGet(p, pReason) );
+ // Yu Hu
+ printf( "%d * %d %d 0\n", p->Counter, PrevId, Inta_ManProofGet(p, pReason) );
+
+ if ( p->Counter == 8371 )
+ {
+ int s = 0;
+ }
+ }
+ PrevId = p->Counter;
+
+ if ( p->pCnf->nClausesA )
+ {
+ if ( p->pVarTypes[Var] == 1 ) // var of A
+ Inta_ManAigOr( p, Inta_ManAigRead(p, pFinal), Inta_ManAigRead(p, pReason) );
+ else
+ Inta_ManAigAnd( p, Inta_ManAigRead(p, pFinal), Inta_ManAigRead(p, pReason) );
+ }
+
+ // resolve the temporary resolvent with the reason clause
+ if ( p->fProofVerif )
+ {
+ int v1, v2;
+
+ // Yu Hu
+ // if ( fPrint )
+ // Inta_ManPrintResolvent( p->pResLits, p->nResLits );
+ if ( fPrint && p->Counter >= 8370 && p->Counter <= 8380 ) {
+ printf("pivot = %d,\n", lit_print(p->pTrail[i]));
+ Inta_ManPrintClauseEx( p->pResLits, p->nResLits);
+ }
+
+ // check that the var is present in the resolvent
+ for ( v1 = 0; v1 < p->nResLits; v1++ )
+ if ( lit_var(p->pResLits[v1]) == Var )
+ break;
+ if ( v1 == p->nResLits )
+ printf( "Recording clause %d: Cannot find variable %d in the temporary resolvent.\n", pFinal->Id, Var );
+ if ( p->pResLits[v1] != lit_neg(pReason->pLits[0]) )
+ printf( "Recording clause %d: The resolved variable %d is in the wrong polarity.\n", pFinal->Id, Var );
+ // remove this variable from the resolvent
+ assert( lit_var(p->pResLits[v1]) == Var );
+ p->nResLits--;
+ for ( ; v1 < p->nResLits; v1++ )
+ p->pResLits[v1] = p->pResLits[v1+1];
+ // add variables of the reason clause
+ for ( v2 = 1; v2 < (int)pReason->nLits; v2++ )
+ {
+ for ( v1 = 0; v1 < p->nResLits; v1++ )
+ if ( lit_var(p->pResLits[v1]) == lit_var(pReason->pLits[v2]) )
+ break;
+ // if it is a new variable, add it to the resolvent
+ if ( v1 == p->nResLits )
+ {
+ if ( p->nResLits == p->nResLitsAlloc )
+ printf( "Recording clause %d: Ran out of space for intermediate resolvent.\n", pFinal->Id );
+ p->pResLits[ p->nResLits++ ] = pReason->pLits[v2];
+ continue;
+ }
+ // if the variable is the same, the literal should be the same too
+ if ( p->pResLits[v1] == pReason->pLits[v2] )
+ continue;
+ // the literal is different
+ printf( "Recording clause %d: Trying to resolve the clause with more than one opposite literal.\n", pFinal->Id );
+ }
+
+ // Yu Hu
+ if ( fPrint && p->Counter >= 8370 && p->Counter <= 8380 ) {
+ Inta_ManPrintClauseEx( pReason->pLits, pReason->nLits);
+ Inta_ManPrintResolvent( p->pResLits, p->nResLits);
+ }
+
+ }
+// Vec_PtrPush( pFinal->pAntis, pReason );
+ }
+
+ // unmark all seen variables
+// for ( i = p->nTrailSize - 1; i >= 0; i-- )
+// p->pSeens[lit_var(p->pTrail[i])] = 0;
+ // check that the literals are unmarked
+// for ( i = p->nTrailSize - 1; i >= 0; i-- )
+// assert( p->pSeens[lit_var(p->pTrail[i])] == 0 );
+
+ // use the resulting clause to check the correctness of resolution
+ if ( p->fProofVerif )
+ {
+ int v1, v2;
+
+ // Yu Hu
+// if ( fPrint )
+// Inta_ManPrintResolvent( p->pResLits, p->nResLits );
+
+ for ( v1 = 0; v1 < p->nResLits; v1++ )
+ {
+ for ( v2 = 0; v2 < (int)pFinal->nLits; v2++ )
+ if ( pFinal->pLits[v2] == p->pResLits[v1] )
+ break;
+ if ( v2 < (int)pFinal->nLits )
+ continue;
+ break;
+ }
+ if ( v1 < p->nResLits )
+ {
+ printf( "Recording clause %d: The final resolvent is wrong.\n", pFinal->Id );
+ Inta_ManPrintClause( p, pConflict );
+ Inta_ManPrintResolvent( p->pResLits, p->nResLits );
+ Inta_ManPrintClause( p, pFinal );
+ }
+
+ // if there are literals in the clause that are not in the resolvent
+ // it means that the derived resolvent is stronger than the clause
+ // we can replace the clause with the resolvent by removing these literals
+ if ( p->nResLits != (int)pFinal->nLits )
+ {
+ for ( v1 = 0; v1 < (int)pFinal->nLits; v1++ )
+ {
+ for ( v2 = 0; v2 < p->nResLits; v2++ )
+ if ( pFinal->pLits[v1] == p->pResLits[v2] )
+ break;
+ if ( v2 < p->nResLits )
+ continue;
+ // remove literal v1 from the final clause
+ pFinal->nLits--;
+ for ( v2 = v1; v2 < (int)pFinal->nLits; v2++ )
+ pFinal->pLits[v2] = pFinal->pLits[v2+1];
+ v1--;
+ }
+ assert( p->nResLits == (int)pFinal->nLits );
+ }
+ }
+p->timeTrace += clock() - clk;
+
+ // return the proof pointer
+ if ( p->pCnf->nClausesA )
+ {
+// Inta_ManPrintInterOne( p, pFinal );
+ }
+ Inta_ManProofSet( p, pFinal, p->Counter );
+ if ( pFinal->Id == 5552 || pFinal->Id == 5553 )
+ {
+ int x = 0;
+ }
+
+ if ( p->pProofNums[pFinal->Id] == p->pProofNums[pFinal->Id-1] )
+ p->pProofNums[pFinal->Id] = p->pProofNums[pConflict->Id];
+
+ return p->Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Records the proof for one clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Inta_ManProofRecordOne( Inta_Man_t * p, Sto_Cls_t * pClause )
+{
+ Sto_Cls_t * pConflict;
+ int i;
+
+ // empty clause never ends up there
+ assert( pClause->nLits > 0 );
+ if ( pClause->nLits == 0 )
+ printf( "Error: Empty clause is attempted.\n" );
+
+ assert( !pClause->fRoot );
+ assert( p->nTrailSize == p->nRootSize );
+
+ // if any of the clause literals are already assumed
+ // it means that the clause is redundant and can be skipped
+ for ( i = 0; i < (int)pClause->nLits; i++ )
+ if ( p->pAssigns[lit_var(pClause->pLits[i])] == pClause->pLits[i] )
+ return 1;
+
+ // add assumptions to the trail
+ for ( i = 0; i < (int)pClause->nLits; i++ )
+ if ( !Inta_ManEnqueue( p, lit_neg(pClause->pLits[i]), NULL ) )
+ {
+ assert( 0 ); // impossible
+ return 0;
+ }
+
+ // propagate the assumptions
+ pConflict = Inta_ManPropagate( p, p->nRootSize );
+ if ( pConflict == NULL )
+ {
+ assert( 0 ); // cannot prove
+ return 0;
+ }
+
+ // construct the proof
+ Inta_ManProofTraceOne( p, pConflict, pClause );
+
+ // undo to the root level
+ Inta_ManCancelUntil( p, p->nRootSize );
+
+ // add large clauses to the watched lists
+ if ( pClause->nLits > 1 )
+ {
+ Inta_ManWatchClause( p, pClause, pClause->pLits[0] );
+ Inta_ManWatchClause( p, pClause, pClause->pLits[1] );
+ return 1;
+ }
+ assert( pClause->nLits == 1 );
+
+ // if the clause proved is unit, add it and propagate
+ if ( !Inta_ManEnqueue( p, pClause->pLits[0], pClause ) )
+ {
+ assert( 0 ); // impossible
+ return 0;
+ }
+
+ // propagate the assumption
+ pConflict = Inta_ManPropagate( p, p->nRootSize );
+ if ( pConflict )
+ {
+ // construct the proof
+ Inta_ManProofTraceOne( p, pConflict, p->pCnf->pEmpty );
+// if ( p->fVerbose )
+// printf( "Found last conflict after adding unit clause number %d!\n", pClause->Id );
+ return 0;
+ }
+
+ // update the root level
+ p->nRootSize = p->nTrailSize;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate the root clauses.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Inta_ManProcessRoots( Inta_Man_t * p )
+{
+ Sto_Cls_t * pClause;
+ int Counter;
+
+ // make sure the root clauses are preceeding the learnt clauses
+ Counter = 0;
+ Sto_ManForEachClause( p->pCnf, pClause )
+ {
+ assert( (int)pClause->fA == (Counter < (int)p->pCnf->nClausesA) );
+ assert( (int)pClause->fRoot == (Counter < (int)p->pCnf->nRoots) );
+ Counter++;
+ }
+ assert( p->pCnf->nClauses == Counter );
+
+ // make sure the last clause if empty
+ assert( p->pCnf->pTail->nLits == 0 );
+
+ // go through the root unit clauses
+ p->nTrailSize = 0;
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ {
+ // create watcher lists for the root clauses
+ if ( pClause->nLits > 1 )
+ {
+ Inta_ManWatchClause( p, pClause, pClause->pLits[0] );
+ Inta_ManWatchClause( p, pClause, pClause->pLits[1] );
+ }
+ // empty clause and large clauses
+ if ( pClause->nLits != 1 )
+ continue;
+ // unit clause
+ assert( lit_check(pClause->pLits[0], p->pCnf->nVars) );
+ if ( !Inta_ManEnqueue( p, pClause->pLits[0], pClause ) )
+ {
+ // detected root level conflict
+// printf( "Error in Inta_ManProcessRoots(): Detected a root-level conflict too early!\n" );
+// assert( 0 );
+ // detected root level conflict
+ Inta_ManProofTraceOne( p, pClause, p->pCnf->pEmpty );
+ if ( p->fVerbose )
+ printf( "Found root level conflict!\n" );
+ return 0;
+ }
+ }
+
+ // propagate the root unit clauses
+ pClause = Inta_ManPropagate( p, 0 );
+ if ( pClause )
+ {
+ // detected root level conflict
+ Inta_ManProofTraceOne( p, pClause, p->pCnf->pEmpty );
+ if ( p->fVerbose )
+ printf( "Found root level conflict!\n" );
+ return 0;
+ }
+
+ // set the root level
+ p->nRootSize = p->nTrailSize;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Records the proof.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManPrepareInter( Inta_Man_t * p )
+{
+ Sto_Cls_t * pClause;
+ int Var, VarAB, v;
+
+ // set interpolants for root clauses
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ {
+ if ( !pClause->fA ) // clause of B
+ {
+ Inta_ManAigFill( p, Inta_ManAigRead(p, pClause) );
+// Inta_ManPrintInterOne( p, pClause );
+ continue;
+ }
+ // clause of A
+ Inta_ManAigClear( p, Inta_ManAigRead(p, pClause) );
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ {
+ Var = lit_var(pClause->pLits[v]);
+ if ( p->pVarTypes[Var] < 0 ) // global var
+ {
+ VarAB = -p->pVarTypes[Var]-1;
+ assert( VarAB >= 0 && VarAB < Vec_IntSize(p->vVarsAB) );
+ if ( lit_sign(pClause->pLits[v]) ) // negative var
+ Inta_ManAigOrNotVar( p, Inta_ManAigRead(p, pClause), VarAB );
+ else
+ Inta_ManAigOrVar( p, Inta_ManAigRead(p, pClause), VarAB );
+ }
+ }
+// Inta_ManPrintInterOne( p, pClause );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes interpolant for the given CNF.]
+
+ Description [Takes the interpolation manager, the CNF deriving by the SAT
+ solver, which includes ClausesA, ClausesB, and learned clauses. Additional
+ arguments are the vector of variables common to AB and the verbosiness flag.
+ Returns the AIG manager with a single output, containing the interpolant.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Inta_ManInterpolate( Inta_Man_t * p, Sto_Man_t * pCnf, void * vVarsAB, int fVerbose )
+{
+ Aig_Man_t * pRes;
+ Aig_Obj_t * pObj;
+ Sto_Cls_t * pClause;
+ int RetValue = 1;
+ int clkTotal = clock();
+
+ // check that the CNF makes sense
+ assert( pCnf->nVars > 0 && pCnf->nClauses > 0 );
+ p->pCnf = pCnf;
+ p->fVerbose = fVerbose;
+ p->vVarsAB = vVarsAB;
+ p->pAig = pRes = Aig_ManStart( 10000 );
+ Aig_IthVar( p->pAig, Vec_IntSize(p->vVarsAB) - 1 );
+
+ // adjust the manager
+ Inta_ManResize( p );
+
+ // prepare the interpolant computation
+ Inta_ManPrepareInter( p );
+
+ // construct proof for each clause
+ // start the proof
+ if ( p->fProofWrite )
+ {
+ p->pFile = fopen( "proof.cnf_", "w" );
+ p->Counter = 0;
+ }
+
+ // write the root clauses
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ Inta_ManProofWriteOne( p, pClause );
+
+ // propagate root level assignments
+ if ( Inta_ManProcessRoots( p ) )
+ {
+ // if there is no conflict, consider learned clauses
+ Sto_ManForEachClause( p->pCnf, pClause )
+ {
+ if ( pClause->Id == 5552 )
+ {
+ int s = 0;
+ }
+ if ( pClause->fRoot )
+ continue;
+ if ( !Inta_ManProofRecordOne( p, pClause ) )
+ {
+ RetValue = 0;
+ break;
+ }
+ }
+ }
+
+ // stop the proof
+ if ( p->fProofWrite )
+ {
+ fclose( p->pFile );
+ p->pFile = NULL;
+ }
+
+ if ( fVerbose )
+ {
+// PRT( "Interpo", clock() - clkTotal );
+ printf( "Vars = %d. Roots = %d. Learned = %d. Resol steps = %d. Ave = %.2f. Mem = %.2f Mb\n",
+ p->pCnf->nVars, p->pCnf->nRoots, p->pCnf->nClauses-p->pCnf->nRoots, p->Counter,
+ 1.0*(p->Counter-p->pCnf->nRoots)/(p->pCnf->nClauses-p->pCnf->nRoots),
+ 1.0*Sto_ManMemoryReport(p->pCnf)/(1<<20) );
+p->timeTotal += clock() - clkTotal;
+ }
+
+ pObj = *Inta_ManAigRead( p, p->pCnf->pTail );
+ Aig_ObjCreatePo( pRes, pObj );
+ Aig_ManCleanup( pRes );
+
+ p->pAig = NULL;
+ return pRes;
+
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Inta_ManDeriveClauses( Inta_Man_t * pMan, Sto_Man_t * pCnf, int fClausesA )
+{
+ Aig_Man_t * p;
+ Aig_Obj_t * pMiter, * pSum, * pLit;
+ Sto_Cls_t * pClause;
+ int Var, VarAB, v;
+ p = Aig_ManStart( 10000 );
+ pMiter = Aig_ManConst1(p);
+ Sto_ManForEachClauseRoot( pCnf, pClause )
+ {
+ if ( fClausesA ^ pClause->fA ) // clause of B
+ continue;
+ // clause of A
+ pSum = Aig_ManConst0(p);
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ {
+ Var = lit_var(pClause->pLits[v]);
+ if ( pMan->pVarTypes[Var] < 0 ) // global var
+ {
+ VarAB = -pMan->pVarTypes[Var]-1;
+ assert( VarAB >= 0 && VarAB < Vec_IntSize(pMan->vVarsAB) );
+ pLit = Aig_NotCond( Aig_IthVar(p, VarAB), lit_sign(pClause->pLits[v]) );
+ }
+ else
+ pLit = Aig_NotCond( Aig_IthVar(p, Vec_IntSize(pMan->vVarsAB)+1+Var), lit_sign(pClause->pLits[v]) );
+ pSum = Aig_Or( p, pSum, pLit );
+ }
+ pMiter = Aig_And( p, pMiter, pSum );
+ }
+ Aig_ObjCreatePo( p, pMiter );
+ return p;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/sat/bsat/satInterA_old.c b/src/sat/bsat/satInterA_old.c
new file mode 100644
index 00000000..57628989
--- /dev/null
+++ b/src/sat/bsat/satInterA_old.c
@@ -0,0 +1,1047 @@
+/**CFile****************************************************************
+
+ FileName [satInter.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT sat_solver.]
+
+ Synopsis [Interpolation package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: satInter.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
+
+***********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include "satStore.h"
+#include "aig.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// variable assignments
+static const lit LIT_UNDEF = 0xffffffff;
+
+// interpolation manager
+struct Inta_Man_t_
+{
+ // clauses of the problems
+ Sto_Man_t * pCnf; // the set of CNF clauses for A and B
+ Vec_Int_t * vVarsAB; // the array of global variables
+ // various parameters
+ int fVerbose; // verbosiness flag
+ int fProofVerif; // verifies the proof
+ int fProofWrite; // writes the proof file
+ int nVarsAlloc; // the allocated size of var arrays
+ int nClosAlloc; // the allocated size of clause arrays
+ // internal BCP
+ int nRootSize; // the number of root level assignments
+ int nTrailSize; // the number of assignments made
+ lit * pTrail; // chronological order of assignments (size nVars)
+ lit * pAssigns; // assignments by variable (size nVars)
+ char * pSeens; // temporary mark (size nVars)
+ Sto_Cls_t ** pReasons; // reasons for each assignment (size nVars)
+ Sto_Cls_t ** pWatches; // watched clauses for each literal (size 2*nVars)
+ // interpolation data
+ Aig_Man_t * pAig; // the AIG manager for recording the interpolant
+ int * pVarTypes; // variable type (size nVars) [1=A, 0=B, <0=AB]
+ Aig_Obj_t ** pInters; // storage for interpolants as truth tables (size nClauses)
+ int nIntersAlloc; // the allocated size of truth table array
+ // proof recording
+ int Counter; // counter of resolved clauses
+ int * pProofNums; // the proof numbers for each clause (size nClauses)
+ FILE * pFile; // the file for proof recording
+ // internal verification
+ lit * pResLits; // the literals of the resolvent
+ int nResLits; // the number of literals of the resolvent
+ int nResLitsAlloc;// the number of literals of the resolvent
+ // runtime stats
+ int timeBcp; // the runtime for BCP
+ int timeTrace; // the runtime of trace construction
+ int timeTotal; // the total runtime of interpolation
+};
+
+// procedure to get hold of the clauses' truth table
+static inline Aig_Obj_t ** Inta_ManAigRead( Inta_Man_t * pMan, Sto_Cls_t * pCls ) { return pMan->pInters + pCls->Id; }
+static inline void Inta_ManAigClear( Inta_Man_t * pMan, Aig_Obj_t ** p ) { *p = Aig_ManConst0(pMan->pAig); }
+static inline void Inta_ManAigFill( Inta_Man_t * pMan, Aig_Obj_t ** p ) { *p = Aig_ManConst1(pMan->pAig); }
+static inline void Inta_ManAigCopy( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q ) { *p = *q; }
+static inline void Inta_ManAigAnd( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q ) { *p = Aig_And(pMan->pAig, *p, *q); }
+static inline void Inta_ManAigOr( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q ) { *p = Aig_Or(pMan->pAig, *p, *q); }
+static inline void Inta_ManAigOrNot( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q ) { *p = Aig_Or(pMan->pAig, *p, Aig_Not(*q)); }
+static inline void Inta_ManAigOrVar( Inta_Man_t * pMan, Aig_Obj_t ** p, int v ) { *p = Aig_Or(pMan->pAig, *p, Aig_IthVar(pMan->pAig, v)); }
+static inline void Inta_ManAigOrNotVar( Inta_Man_t * pMan, Aig_Obj_t ** p, int v ) { *p = Aig_Or(pMan->pAig, *p, Aig_Not(Aig_IthVar(pMan->pAig, v))); }
+
+// reading/writing the proof for a clause
+static inline int Inta_ManProofGet( Inta_Man_t * p, Sto_Cls_t * pCls ) { return p->pProofNums[pCls->Id]; }
+static inline void Inta_ManProofSet( Inta_Man_t * p, Sto_Cls_t * pCls, int n ) { p->pProofNums[pCls->Id] = n; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocate proof manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Inta_Man_t * Inta_ManAlloc()
+{
+ Inta_Man_t * p;
+ // allocate the manager
+ p = (Inta_Man_t *)malloc( sizeof(Inta_Man_t) );
+ memset( p, 0, sizeof(Inta_Man_t) );
+ // verification
+ p->nResLitsAlloc = (1<<16);
+ p->pResLits = malloc( sizeof(lit) * p->nResLitsAlloc );
+ // parameters
+ p->fProofWrite = 0;
+ p->fProofVerif = 1;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Count common variables in the clauses of A and B.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Inta_ManGlobalVars( Inta_Man_t * p )
+{
+ Sto_Cls_t * pClause;
+ int LargeNum = -100000000;
+ int Var, nVarsAB, v;
+
+ // mark the variable encountered in the clauses of A
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ {
+ if ( !pClause->fA )
+ break;
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ p->pVarTypes[lit_var(pClause->pLits[v])] = 1;
+ }
+
+ // check variables that appear in clauses of B
+ nVarsAB = 0;
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ {
+ if ( pClause->fA )
+ continue;
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ {
+ Var = lit_var(pClause->pLits[v]);
+ if ( p->pVarTypes[Var] == 1 ) // var of A
+ {
+ // change it into a global variable
+ nVarsAB++;
+ p->pVarTypes[Var] = LargeNum;
+ }
+ }
+ }
+ assert( nVarsAB <= Vec_IntSize(p->vVarsAB) );
+
+ // order global variables
+ nVarsAB = 0;
+ Vec_IntForEachEntry( p->vVarsAB, Var, v )
+ p->pVarTypes[Var] = -(1+nVarsAB++);
+
+ // check that there is no extra global variables
+ for ( v = 0; v < p->pCnf->nVars; v++ )
+ assert( p->pVarTypes[v] != LargeNum );
+ return nVarsAB;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resize proof manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManResize( Inta_Man_t * p )
+{
+ // check if resizing is needed
+ if ( p->nVarsAlloc < p->pCnf->nVars )
+ {
+ // find the new size
+ if ( p->nVarsAlloc == 0 )
+ p->nVarsAlloc = 1;
+ while ( p->nVarsAlloc < p->pCnf->nVars )
+ p->nVarsAlloc *= 2;
+ // resize the arrays
+ p->pTrail = (lit *) realloc( p->pTrail, sizeof(lit) * p->nVarsAlloc );
+ p->pAssigns = (lit *) realloc( p->pAssigns, sizeof(lit) * p->nVarsAlloc );
+ p->pSeens = (char *) realloc( p->pSeens, sizeof(char) * p->nVarsAlloc );
+ p->pVarTypes = (int *) realloc( p->pVarTypes, sizeof(int) * p->nVarsAlloc );
+ p->pReasons = (Sto_Cls_t **)realloc( p->pReasons, sizeof(Sto_Cls_t *) * p->nVarsAlloc );
+ p->pWatches = (Sto_Cls_t **)realloc( p->pWatches, sizeof(Sto_Cls_t *) * p->nVarsAlloc*2 );
+ }
+
+ // clean the free space
+ memset( p->pAssigns , 0xff, sizeof(lit) * p->pCnf->nVars );
+ memset( p->pSeens , 0, sizeof(char) * p->pCnf->nVars );
+ memset( p->pVarTypes, 0, sizeof(int) * p->pCnf->nVars );
+ memset( p->pReasons , 0, sizeof(Sto_Cls_t *) * p->pCnf->nVars );
+ memset( p->pWatches , 0, sizeof(Sto_Cls_t *) * p->pCnf->nVars*2 );
+
+ // compute the number of common variables
+ Inta_ManGlobalVars( p );
+
+ // check if resizing of clauses is needed
+ if ( p->nClosAlloc < p->pCnf->nClauses )
+ {
+ // find the new size
+ if ( p->nClosAlloc == 0 )
+ p->nClosAlloc = 1;
+ while ( p->nClosAlloc < p->pCnf->nClauses )
+ p->nClosAlloc *= 2;
+ // resize the arrays
+ p->pProofNums = (int *) realloc( p->pProofNums, sizeof(int) * p->nClosAlloc );
+ }
+ memset( p->pProofNums, 0, sizeof(int) * p->pCnf->nClauses );
+
+ // check if resizing of truth tables is needed
+ if ( p->nIntersAlloc < p->pCnf->nClauses )
+ {
+ p->nIntersAlloc = p->pCnf->nClauses;
+ p->pInters = (Aig_Obj_t **) realloc( p->pInters, sizeof(Aig_Obj_t *) * p->nIntersAlloc );
+ }
+ memset( p->pInters, 0, sizeof(Aig_Obj_t *) * p->pCnf->nClauses );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deallocate proof manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManFree( Inta_Man_t * p )
+{
+/*
+ printf( "Runtime stats:\n" );
+PRT( "BCP ", p->timeBcp );
+PRT( "Trace ", p->timeTrace );
+PRT( "TOTAL ", p->timeTotal );
+*/
+ free( p->pInters );
+ free( p->pProofNums );
+ free( p->pTrail );
+ free( p->pAssigns );
+ free( p->pSeens );
+ free( p->pVarTypes );
+ free( p->pReasons );
+ free( p->pWatches );
+ free( p->pResLits );
+ free( p );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints the clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManPrintClause( Inta_Man_t * p, Sto_Cls_t * pClause )
+{
+ int i;
+ printf( "Clause ID = %d. Proof = %d. {", pClause->Id, Inta_ManProofGet(p, pClause) );
+ for ( i = 0; i < (int)pClause->nLits; i++ )
+ printf( " %d", pClause->pLits[i] );
+ printf( " }\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the resolvent.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManPrintResolvent( lit * pResLits, int nResLits )
+{
+ int i;
+ printf( "Resolvent: {" );
+ for ( i = 0; i < nResLits; i++ )
+ printf( " %d", pResLits[i] );
+ printf( " }\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the interpolant for one clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManPrintInterOne( Inta_Man_t * p, Sto_Cls_t * pClause )
+{
+ printf( "Clause %2d : ", pClause->Id );
+// Extra_PrintBinary___( stdout, Inta_ManAigRead(p, pClause), (1 << p->nVarsAB) );
+ printf( "\n" );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Adds one clause to the watcher list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Inta_ManWatchClause( Inta_Man_t * p, Sto_Cls_t * pClause, lit Lit )
+{
+ assert( lit_check(Lit, p->pCnf->nVars) );
+ if ( pClause->pLits[0] == Lit )
+ pClause->pNext0 = p->pWatches[lit_neg(Lit)];
+ else
+ {
+ assert( pClause->pLits[1] == Lit );
+ pClause->pNext1 = p->pWatches[lit_neg(Lit)];
+ }
+ p->pWatches[lit_neg(Lit)] = pClause;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Records implication.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Inta_ManEnqueue( Inta_Man_t * p, lit Lit, Sto_Cls_t * pReason )
+{
+ int Var = lit_var(Lit);
+ if ( p->pAssigns[Var] != LIT_UNDEF )
+ return p->pAssigns[Var] == Lit;
+ p->pAssigns[Var] = Lit;
+ p->pReasons[Var] = pReason;
+ p->pTrail[p->nTrailSize++] = Lit;
+//printf( "assigning var %d value %d\n", Var, !lit_sign(Lit) );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Records implication.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Inta_ManCancelUntil( Inta_Man_t * p, int Level )
+{
+ lit Lit;
+ int i, Var;
+ for ( i = p->nTrailSize - 1; i >= Level; i-- )
+ {
+ Lit = p->pTrail[i];
+ Var = lit_var( Lit );
+ p->pReasons[Var] = NULL;
+ p->pAssigns[Var] = LIT_UNDEF;
+//printf( "cancelling var %d\n", Var );
+ }
+ p->nTrailSize = Level;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate one assignment.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Sto_Cls_t * Inta_ManPropagateOne( Inta_Man_t * p, lit Lit )
+{
+ Sto_Cls_t ** ppPrev, * pCur, * pTemp;
+ lit LitF = lit_neg(Lit);
+ int i;
+ // iterate through the literals
+ ppPrev = p->pWatches + Lit;
+ for ( pCur = p->pWatches[Lit]; pCur; pCur = *ppPrev )
+ {
+ // make sure the false literal is in the second literal of the clause
+ if ( pCur->pLits[0] == LitF )
+ {
+ pCur->pLits[0] = pCur->pLits[1];
+ pCur->pLits[1] = LitF;
+ pTemp = pCur->pNext0;
+ pCur->pNext0 = pCur->pNext1;
+ pCur->pNext1 = pTemp;
+ }
+ assert( pCur->pLits[1] == LitF );
+
+ // if the first literal is true, the clause is satisfied
+ if ( pCur->pLits[0] == p->pAssigns[lit_var(pCur->pLits[0])] )
+ {
+ ppPrev = &pCur->pNext1;
+ continue;
+ }
+
+ // look for a new literal to watch
+ for ( i = 2; i < (int)pCur->nLits; i++ )
+ {
+ // skip the case when the literal is false
+ if ( lit_neg(pCur->pLits[i]) == p->pAssigns[lit_var(pCur->pLits[i])] )
+ continue;
+ // the literal is either true or unassigned - watch it
+ pCur->pLits[1] = pCur->pLits[i];
+ pCur->pLits[i] = LitF;
+ // remove this clause from the watch list of Lit
+ *ppPrev = pCur->pNext1;
+ // add this clause to the watch list of pCur->pLits[i] (now it is pCur->pLits[1])
+ Inta_ManWatchClause( p, pCur, pCur->pLits[1] );
+ break;
+ }
+ if ( i < (int)pCur->nLits ) // found new watch
+ continue;
+
+ // clause is unit - enqueue new implication
+ if ( Inta_ManEnqueue(p, pCur->pLits[0], pCur) )
+ {
+ ppPrev = &pCur->pNext1;
+ continue;
+ }
+
+ // conflict detected - return the conflict clause
+ return pCur;
+ }
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate the current assignments.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Sto_Cls_t * Inta_ManPropagate( Inta_Man_t * p, int Start )
+{
+ Sto_Cls_t * pClause;
+ int i;
+ int clk = clock();
+ for ( i = Start; i < p->nTrailSize; i++ )
+ {
+ pClause = Inta_ManPropagateOne( p, p->pTrail[i] );
+ if ( pClause )
+ {
+p->timeBcp += clock() - clk;
+ return pClause;
+ }
+ }
+p->timeBcp += clock() - clk;
+ return NULL;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes one root clause into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManProofWriteOne( Inta_Man_t * p, Sto_Cls_t * pClause )
+{
+ Inta_ManProofSet( p, pClause, ++p->Counter );
+
+ if ( p->fProofWrite )
+ {
+ int v;
+ fprintf( p->pFile, "%d", Inta_ManProofGet(p, pClause) );
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ fprintf( p->pFile, " %d", lit_print(pClause->pLits[v]) );
+ fprintf( p->pFile, " 0 0\n" );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Traces the proof for one clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pFinal )
+{
+ Sto_Cls_t * pReason;
+ int i, v, Var, PrevId;
+ int fPrint = 0;
+ int clk = clock();
+
+ // collect resolvent literals
+ if ( p->fProofVerif )
+ {
+ assert( (int)pConflict->nLits <= p->nResLitsAlloc );
+ memcpy( p->pResLits, pConflict->pLits, sizeof(lit) * pConflict->nLits );
+ p->nResLits = pConflict->nLits;
+ }
+
+ // mark all the variables in the conflict as seen
+ for ( v = 0; v < (int)pConflict->nLits; v++ )
+ p->pSeens[lit_var(pConflict->pLits[v])] = 1;
+
+ // start the anticedents
+// pFinal->pAntis = Vec_PtrAlloc( 32 );
+// Vec_PtrPush( pFinal->pAntis, pConflict );
+
+ if ( p->pCnf->nClausesA )
+ Inta_ManAigCopy( p, Inta_ManAigRead(p, pFinal), Inta_ManAigRead(p, pConflict) );
+
+ // follow the trail backwards
+ PrevId = Inta_ManProofGet(p, pConflict);
+ for ( i = p->nTrailSize - 1; i >= 0; i-- )
+ {
+ // skip literals that are not involved
+ Var = lit_var(p->pTrail[i]);
+ if ( !p->pSeens[Var] )
+ continue;
+ p->pSeens[Var] = 0;
+
+ // skip literals of the resulting clause
+ pReason = p->pReasons[Var];
+ if ( pReason == NULL )
+ continue;
+ assert( p->pTrail[i] == pReason->pLits[0] );
+
+ // add the variables to seen
+ for ( v = 1; v < (int)pReason->nLits; v++ )
+ p->pSeens[lit_var(pReason->pLits[v])] = 1;
+
+ // record the reason clause
+ assert( Inta_ManProofGet(p, pReason) > 0 );
+ p->Counter++;
+ if ( p->fProofWrite )
+ fprintf( p->pFile, "%d * %d %d 0\n", p->Counter, PrevId, Inta_ManProofGet(p, pReason) );
+ PrevId = p->Counter;
+
+ if ( p->pCnf->nClausesA )
+ {
+ if ( p->pVarTypes[Var] == 1 ) // var of A
+ Inta_ManAigOr( p, Inta_ManAigRead(p, pFinal), Inta_ManAigRead(p, pReason) );
+ else
+ Inta_ManAigAnd( p, Inta_ManAigRead(p, pFinal), Inta_ManAigRead(p, pReason) );
+ }
+
+ // resolve the temporary resolvent with the reason clause
+ if ( p->fProofVerif )
+ {
+ int v1, v2;
+ if ( fPrint )
+ Inta_ManPrintResolvent( p->pResLits, p->nResLits );
+ // check that the var is present in the resolvent
+ for ( v1 = 0; v1 < p->nResLits; v1++ )
+ if ( lit_var(p->pResLits[v1]) == Var )
+ break;
+ if ( v1 == p->nResLits )
+ printf( "Recording clause %d: Cannot find variable %d in the temporary resolvent.\n", pFinal->Id, Var );
+ if ( p->pResLits[v1] != lit_neg(pReason->pLits[0]) )
+ printf( "Recording clause %d: The resolved variable %d is in the wrong polarity.\n", pFinal->Id, Var );
+ // remove this variable from the resolvent
+ assert( lit_var(p->pResLits[v1]) == Var );
+ p->nResLits--;
+ for ( ; v1 < p->nResLits; v1++ )
+ p->pResLits[v1] = p->pResLits[v1+1];
+ // add variables of the reason clause
+ for ( v2 = 1; v2 < (int)pReason->nLits; v2++ )
+ {
+ for ( v1 = 0; v1 < p->nResLits; v1++ )
+ if ( lit_var(p->pResLits[v1]) == lit_var(pReason->pLits[v2]) )
+ break;
+ // if it is a new variable, add it to the resolvent
+ if ( v1 == p->nResLits )
+ {
+ if ( p->nResLits == p->nResLitsAlloc )
+ printf( "Recording clause %d: Ran out of space for intermediate resolvent.\n", pFinal->Id );
+ p->pResLits[ p->nResLits++ ] = pReason->pLits[v2];
+ continue;
+ }
+ // if the variable is the same, the literal should be the same too
+ if ( p->pResLits[v1] == pReason->pLits[v2] )
+ continue;
+ // the literal is different
+ printf( "Recording clause %d: Trying to resolve the clause with more than one opposite literal.\n", pFinal->Id );
+ }
+ }
+// Vec_PtrPush( pFinal->pAntis, pReason );
+ }
+
+ // unmark all seen variables
+// for ( i = p->nTrailSize - 1; i >= 0; i-- )
+// p->pSeens[lit_var(p->pTrail[i])] = 0;
+ // check that the literals are unmarked
+// for ( i = p->nTrailSize - 1; i >= 0; i-- )
+// assert( p->pSeens[lit_var(p->pTrail[i])] == 0 );
+
+ // use the resulting clause to check the correctness of resolution
+ if ( p->fProofVerif )
+ {
+ int v1, v2;
+ if ( fPrint )
+ Inta_ManPrintResolvent( p->pResLits, p->nResLits );
+ for ( v1 = 0; v1 < p->nResLits; v1++ )
+ {
+ for ( v2 = 0; v2 < (int)pFinal->nLits; v2++ )
+ if ( pFinal->pLits[v2] == p->pResLits[v1] )
+ break;
+ if ( v2 < (int)pFinal->nLits )
+ continue;
+ break;
+ }
+ if ( v1 < p->nResLits )
+ {
+ printf( "Recording clause %d: The final resolvent is wrong.\n", pFinal->Id );
+ Inta_ManPrintClause( p, pConflict );
+ Inta_ManPrintResolvent( p->pResLits, p->nResLits );
+ Inta_ManPrintClause( p, pFinal );
+ }
+
+ // if there are literals in the clause that are not in the resolvent
+ // it means that the derived resolvent is stronger than the clause
+ // we can replace the clause with the resolvent by removing these literals
+ if ( p->nResLits != (int)pFinal->nLits )
+ {
+ for ( v1 = 0; v1 < (int)pFinal->nLits; v1++ )
+ {
+ for ( v2 = 0; v2 < p->nResLits; v2++ )
+ if ( pFinal->pLits[v1] == p->pResLits[v2] )
+ break;
+ if ( v2 < p->nResLits )
+ continue;
+ // remove literal v1 from the final clause
+ pFinal->nLits--;
+ for ( v2 = v1; v2 < (int)pFinal->nLits; v2++ )
+ pFinal->pLits[v2] = pFinal->pLits[v2+1];
+ v1--;
+ }
+ assert( p->nResLits == (int)pFinal->nLits );
+ }
+ }
+p->timeTrace += clock() - clk;
+
+ // return the proof pointer
+ if ( p->pCnf->nClausesA )
+ {
+// Inta_ManPrintInterOne( p, pFinal );
+ }
+ Inta_ManProofSet( p, pFinal, p->Counter );
+ return p->Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Records the proof for one clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Inta_ManProofRecordOne( Inta_Man_t * p, Sto_Cls_t * pClause )
+{
+ Sto_Cls_t * pConflict;
+ int i;
+
+ // empty clause never ends up there
+ assert( pClause->nLits > 0 );
+ if ( pClause->nLits == 0 )
+ printf( "Error: Empty clause is attempted.\n" );
+
+ assert( !pClause->fRoot );
+ assert( p->nTrailSize == p->nRootSize );
+
+ // if any of the clause literals are already assumed
+ // it means that the clause is redundant and can be skipped
+ for ( i = 0; i < (int)pClause->nLits; i++ )
+ if ( p->pAssigns[lit_var(pClause->pLits[i])] == pClause->pLits[i] )
+ return 1;
+
+ // add assumptions to the trail
+ for ( i = 0; i < (int)pClause->nLits; i++ )
+ if ( !Inta_ManEnqueue( p, lit_neg(pClause->pLits[i]), NULL ) )
+ {
+ assert( 0 ); // impossible
+ return 0;
+ }
+
+ // propagate the assumptions
+ pConflict = Inta_ManPropagate( p, p->nRootSize );
+ if ( pConflict == NULL )
+ {
+ assert( 0 ); // cannot prove
+ return 0;
+ }
+
+ // construct the proof
+ Inta_ManProofTraceOne( p, pConflict, pClause );
+
+ // undo to the root level
+ Inta_ManCancelUntil( p, p->nRootSize );
+
+ // add large clauses to the watched lists
+ if ( pClause->nLits > 1 )
+ {
+ Inta_ManWatchClause( p, pClause, pClause->pLits[0] );
+ Inta_ManWatchClause( p, pClause, pClause->pLits[1] );
+ return 1;
+ }
+ assert( pClause->nLits == 1 );
+
+ // if the clause proved is unit, add it and propagate
+ if ( !Inta_ManEnqueue( p, pClause->pLits[0], pClause ) )
+ {
+ assert( 0 ); // impossible
+ return 0;
+ }
+
+ // propagate the assumption
+ pConflict = Inta_ManPropagate( p, p->nRootSize );
+ if ( pConflict )
+ {
+ // construct the proof
+ Inta_ManProofTraceOne( p, pConflict, p->pCnf->pEmpty );
+// if ( p->fVerbose )
+// printf( "Found last conflict after adding unit clause number %d!\n", pClause->Id );
+ return 0;
+ }
+
+ // update the root level
+ p->nRootSize = p->nTrailSize;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate the root clauses.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Inta_ManProcessRoots( Inta_Man_t * p )
+{
+ Sto_Cls_t * pClause;
+ int Counter;
+
+ // make sure the root clauses are preceeding the learnt clauses
+ Counter = 0;
+ Sto_ManForEachClause( p->pCnf, pClause )
+ {
+ assert( (int)pClause->fA == (Counter < (int)p->pCnf->nClausesA) );
+ assert( (int)pClause->fRoot == (Counter < (int)p->pCnf->nRoots) );
+ Counter++;
+ }
+ assert( p->pCnf->nClauses == Counter );
+
+ // make sure the last clause if empty
+ assert( p->pCnf->pTail->nLits == 0 );
+
+ // go through the root unit clauses
+ p->nTrailSize = 0;
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ {
+ // create watcher lists for the root clauses
+ if ( pClause->nLits > 1 )
+ {
+ Inta_ManWatchClause( p, pClause, pClause->pLits[0] );
+ Inta_ManWatchClause( p, pClause, pClause->pLits[1] );
+ }
+ // empty clause and large clauses
+ if ( pClause->nLits != 1 )
+ continue;
+ // unit clause
+ assert( lit_check(pClause->pLits[0], p->pCnf->nVars) );
+ if ( !Inta_ManEnqueue( p, pClause->pLits[0], pClause ) )
+ {
+ // detected root level conflict
+// printf( "Error in Inta_ManProcessRoots(): Detected a root-level conflict too early!\n" );
+// assert( 0 );
+ // detected root level conflict
+ Inta_ManProofTraceOne( p, pClause, p->pCnf->pEmpty );
+ if ( p->fVerbose )
+ printf( "Found root level conflict!\n" );
+ return 0;
+ }
+ }
+
+ // propagate the root unit clauses
+ pClause = Inta_ManPropagate( p, 0 );
+ if ( pClause )
+ {
+ // detected root level conflict
+ Inta_ManProofTraceOne( p, pClause, p->pCnf->pEmpty );
+ if ( p->fVerbose )
+ printf( "Found root level conflict!\n" );
+ return 0;
+ }
+
+ // set the root level
+ p->nRootSize = p->nTrailSize;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Records the proof.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Inta_ManPrepareInter( Inta_Man_t * p )
+{
+ Sto_Cls_t * pClause;
+ int Var, VarAB, v;
+
+ // set interpolants for root clauses
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ {
+ if ( !pClause->fA ) // clause of B
+ {
+ Inta_ManAigFill( p, Inta_ManAigRead(p, pClause) );
+// Inta_ManPrintInterOne( p, pClause );
+ continue;
+ }
+ // clause of A
+ Inta_ManAigClear( p, Inta_ManAigRead(p, pClause) );
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ {
+ Var = lit_var(pClause->pLits[v]);
+ if ( p->pVarTypes[Var] < 0 ) // global var
+ {
+ VarAB = -p->pVarTypes[Var]-1;
+ assert( VarAB >= 0 && VarAB < Vec_IntSize(p->vVarsAB) );
+ if ( lit_sign(pClause->pLits[v]) ) // negative var
+ Inta_ManAigOrNotVar( p, Inta_ManAigRead(p, pClause), VarAB );
+ else
+ Inta_ManAigOrVar( p, Inta_ManAigRead(p, pClause), VarAB );
+ }
+ }
+// Inta_ManPrintInterOne( p, pClause );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes interpolant for the given CNF.]
+
+ Description [Takes the interpolation manager, the CNF deriving by the SAT
+ solver, which includes ClausesA, ClausesB, and learned clauses. Additional
+ arguments are the vector of variables common to AB and the verbosiness flag.
+ Returns the AIG manager with a single output, containing the interpolant.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void * Inta_ManInterpolate( Inta_Man_t * p, Sto_Man_t * pCnf, void * vVarsAB, int fVerbose )
+{
+ Aig_Man_t * pRes;
+ Aig_Obj_t * pObj;
+ Sto_Cls_t * pClause;
+ int RetValue = 1;
+ int clkTotal = clock();
+
+ // check that the CNF makes sense
+ assert( pCnf->nVars > 0 && pCnf->nClauses > 0 );
+ p->pCnf = pCnf;
+ p->fVerbose = fVerbose;
+ p->vVarsAB = vVarsAB;
+ p->pAig = pRes = Aig_ManStart( 10000 );
+ Aig_IthVar( p->pAig, Vec_IntSize(p->vVarsAB) - 1 );
+
+ // adjust the manager
+ Inta_ManResize( p );
+
+ // prepare the interpolant computation
+ Inta_ManPrepareInter( p );
+
+ // construct proof for each clause
+ // start the proof
+ if ( p->fProofWrite )
+ {
+ p->pFile = fopen( "proof.cnf_", "w" );
+ p->Counter = 0;
+ }
+
+ // write the root clauses
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ Inta_ManProofWriteOne( p, pClause );
+
+ // propagate root level assignments
+ if ( Inta_ManProcessRoots( p ) )
+ {
+ // if there is no conflict, consider learned clauses
+ Sto_ManForEachClause( p->pCnf, pClause )
+ {
+ if ( pClause->fRoot )
+ continue;
+ if ( !Inta_ManProofRecordOne( p, pClause ) )
+ {
+ RetValue = 0;
+ break;
+ }
+ }
+ }
+
+ // stop the proof
+ if ( p->fProofWrite )
+ {
+ fclose( p->pFile );
+ p->pFile = NULL;
+ }
+
+ if ( fVerbose )
+ {
+// PRT( "Interpo", clock() - clkTotal );
+ printf( "Vars = %d. Roots = %d. Learned = %d. Resol steps = %d. Ave = %.2f. Mem = %.2f Mb\n",
+ p->pCnf->nVars, p->pCnf->nRoots, p->pCnf->nClauses-p->pCnf->nRoots, p->Counter,
+ 1.0*(p->Counter-p->pCnf->nRoots)/(p->pCnf->nClauses-p->pCnf->nRoots),
+ 1.0*Sto_ManMemoryReport(p->pCnf)/(1<<20) );
+p->timeTotal += clock() - clkTotal;
+ }
+
+ pObj = *Inta_ManAigRead( p, p->pCnf->pTail );
+ Aig_ObjCreatePo( pRes, pObj );
+ Aig_ManCleanup( pRes );
+
+ p->pAig = NULL;
+ return pRes;
+
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Aig_Man_t * Inta_ManDeriveClauses( Inta_Man_t * pMan, Sto_Man_t * pCnf, int fClausesA )
+{
+ Aig_Man_t * p;
+ Aig_Obj_t * pMiter, * pSum, * pLit;
+ Sto_Cls_t * pClause;
+ int Var, VarAB, v;
+ p = Aig_ManStart( 10000 );
+ pMiter = Aig_ManConst1(p);
+ Sto_ManForEachClauseRoot( pCnf, pClause )
+ {
+ if ( fClausesA ^ pClause->fA ) // clause of B
+ continue;
+ // clause of A
+ pSum = Aig_ManConst0(p);
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ {
+ Var = lit_var(pClause->pLits[v]);
+ if ( pMan->pVarTypes[Var] < 0 ) // global var
+ {
+ VarAB = -pMan->pVarTypes[Var]-1;
+ assert( VarAB >= 0 && VarAB < Vec_IntSize(pMan->vVarsAB) );
+ pLit = Aig_NotCond( Aig_IthVar(p, VarAB), lit_sign(pClause->pLits[v]) );
+ }
+ else
+ pLit = Aig_NotCond( Aig_IthVar(p, Vec_IntSize(pMan->vVarsAB)+1+Var), lit_sign(pClause->pLits[v]) );
+ pSum = Aig_Or( p, pSum, pLit );
+ }
+ pMiter = Aig_And( p, pMiter, pSum );
+ }
+ Aig_ObjCreatePo( p, pMiter );
+ return p;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/sat/bsat/satInterA_yu_hu.c b/src/sat/bsat/satInterA_yu_hu.c
index 2005e558..aa2289f2 100644
--- a/src/sat/bsat/satInterA_yu_hu.c
+++ b/src/sat/bsat/satInterA_yu_hu.c
@@ -114,6 +114,7 @@ Inta_Man_t * Inta_ManAlloc()
// parameters
p->fProofWrite = 1;
p->fProofVerif = 1;
+
return p;
}
@@ -289,16 +290,6 @@ void Inta_ManPrintClause( Inta_Man_t * p, Sto_Cls_t * pClause )
printf( " }\n" );
}
-// Yu Hu
-void Inta_ManPrintClauseEx( lit * pResLits, int nResLits )
-{
- int i;
- printf( " {" );
- for ( i = 0; i < nResLits; i++ )
- printf( " %d", lit_print(pResLits[i]) );
- printf( " }\n" );
-}
-
/**Function*************************************************************
Synopsis [Prints the resolvent.]
@@ -315,6 +306,8 @@ void Inta_ManPrintResolvent( lit * pResLits, int nResLits )
int i;
printf( "Resolvent: {" );
for ( i = 0; i < nResLits; i++ )
+ // Yu Hu
+ // printf( " %d", pResLits[i] );
printf( " %d", lit_print(pResLits[i]) );
printf( " }\n" );
}
@@ -537,6 +530,17 @@ void Inta_ManProofWriteOne( Inta_Man_t * p, Sto_Cls_t * pClause )
}
}
+// Yu Hu
+void Inta_ManPrintClauseEx( lit * pResLits, int nResLits )
+{
+ int i;
+ printf( " {" );
+ for ( i = 0; i < nResLits; i++ )
+ printf( " %d", lit_print(pResLits[i]) );
+ printf( " }\n" );
+}
+
+
/**Function*************************************************************
Synopsis [Traces the proof for one clause.]
@@ -594,7 +598,6 @@ int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pF
for ( v = 1; v < (int)pReason->nLits; v++ )
p->pSeens[lit_var(pReason->pLits[v])] = 1;
-
// record the reason clause
assert( Inta_ManProofGet(p, pReason) > 0 );
p->Counter++;
@@ -617,14 +620,15 @@ int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pF
if ( p->fProofVerif )
{
int v1, v2;
+
// Yu Hu
-// if ( fPrint )
-// Inta_ManPrintResolvent( p->pResLits, p->nResLits );
- if ( fPrint ) {
- printf("pivot = %d,\n", lit_print(p->pTrail[i]));
- Inta_ManPrintClauseEx( p->pResLits, p->nResLits);
- }
-
+ // if ( fPrint )
+ // Inta_ManPrintResolvent( p->pResLits, p->nResLits );
+ if ( fPrint ) {
+ printf("pivot = %d,\n", lit_print(p->pTrail[i]));
+ Inta_ManPrintClauseEx( p->pResLits, p->nResLits);
+ }
+
// check that the var is present in the resolvent
for ( v1 = 0; v1 < p->nResLits; v1++ )
if ( lit_var(p->pResLits[v1]) == Var )
@@ -660,12 +664,12 @@ int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pF
}
// Yu Hu
- if ( fPrint ) {
- Inta_ManPrintClauseEx( pReason->pLits, pReason->nLits);
- Inta_ManPrintResolvent( p->pResLits, p->nResLits );
- }
- }
+ if ( fPrint ) {
+ Inta_ManPrintClauseEx( pReason->pLits, pReason->nLits);
+ Inta_ManPrintResolvent( p->pResLits, p->nResLits);
+ }
+ }
// Vec_PtrPush( pFinal->pAntis, pReason );
}
@@ -680,10 +684,11 @@ int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pF
if ( p->fProofVerif )
{
int v1, v2;
- if ( fPrint ){
- // Yu Hu
+
+ // Yu Hu
+// if ( fPrint )
// Inta_ManPrintResolvent( p->pResLits, p->nResLits );
- }
+
for ( v1 = 0; v1 < p->nResLits; v1++ )
{
for ( v2 = 0; v2 < (int)pFinal->nLits; v2++ )
@@ -700,6 +705,27 @@ int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pF
Inta_ManPrintResolvent( p->pResLits, p->nResLits );
Inta_ManPrintClause( p, pFinal );
}
+
+ // if there are literals in the clause that are not in the resolvent
+ // it means that the derived resolvent is stronger than the clause
+ // we can replace the clause with the resolvent by removing these literals
+ if ( p->nResLits != (int)pFinal->nLits )
+ {
+ for ( v1 = 0; v1 < (int)pFinal->nLits; v1++ )
+ {
+ for ( v2 = 0; v2 < p->nResLits; v2++ )
+ if ( pFinal->pLits[v1] == p->pResLits[v2] )
+ break;
+ if ( v2 < p->nResLits )
+ continue;
+ // remove literal v1 from the final clause
+ pFinal->nLits--;
+ for ( v2 = v1; v2 < (int)pFinal->nLits; v2++ )
+ pFinal->pLits[v2] = pFinal->pLits[v2+1];
+ v1--;
+ }
+ assert( p->nResLits == (int)pFinal->nLits );
+ }
}
p->timeTrace += clock() - clk;
@@ -733,9 +759,16 @@ int Inta_ManProofRecordOne( Inta_Man_t * p, Sto_Cls_t * pClause )
if ( pClause->nLits == 0 )
printf( "Error: Empty clause is attempted.\n" );
- // add assumptions to the trail
assert( !pClause->fRoot );
assert( p->nTrailSize == p->nRootSize );
+
+ // if any of the clause literals are already assumed
+ // it means that the clause is redundant and can be skipped
+ for ( i = 0; i < (int)pClause->nLits; i++ )
+ if ( p->pAssigns[lit_var(pClause->pLits[i])] == pClause->pLits[i] )
+ return 1;
+
+ // add assumptions to the trail
for ( i = 0; i < (int)pClause->nLits; i++ )
if ( !Inta_ManEnqueue( p, lit_neg(pClause->pLits[i]), NULL ) )
{
diff --git a/src/sat/lsat/solver.h b/src/sat/lsat/solver.h
new file mode 100644
index 00000000..a15e42d6
--- /dev/null
+++ b/src/sat/lsat/solver.h
@@ -0,0 +1,124 @@
+/****************************************************************************************[solver.h]
+Copyright (c) 2008, Niklas Sorensson
+ 2008, Koen Claessen
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**************************************************************************************************/
+
+#ifndef Minisat_solver_h
+#define Minisat_solver_h
+
+// SolverTypes:
+//
+typedef struct solver_t solver;
+typedef int solver_Var;
+typedef int solver_Lit;
+typedef int solver_lbool;
+
+// Constants: (can these be made inline-able?)
+//
+
+extern const solver_lbool solver_l_True;
+extern const solver_lbool solver_l_False;
+extern const solver_lbool solver_l_Undef;
+
+
+solver* solver_new (void);
+void solver_delete (solver* s);
+
+solver_Var solver_newVar (solver *s);
+solver_Lit solver_newLit (solver *s);
+
+solver_Lit solver_mkLit (solver_Var x);
+solver_Lit solver_mkLit_args (solver_Var x, int sign);
+solver_Lit solver_negate (solver_Lit p);
+
+solver_Var solver_var (solver_Lit p);
+int solver_sign (solver_Lit p);
+
+int solver_addClause (solver *s, int len, solver_Lit *ps);
+void solver_addClause_begin (solver *s);
+void solver_addClause_addLit(solver *s, solver_Lit p);
+int solver_addClause_commit(solver *s);
+
+int solver_simplify (solver *s);
+
+int solver_solve (solver *s, int len, solver_Lit *ps);
+void solver_solve_begin (solver *s);
+void solver_solve_addLit (solver *s, solver_Lit p);
+int solver_solve_commit (solver *s);
+
+int solver_okay (solver *s);
+
+void solver_setPolarity (solver *s, solver_Var v, int b);
+void solver_setDecisionVar (solver *s, solver_Var v, int b);
+
+solver_lbool solver_get_l_True (void);
+solver_lbool solver_get_l_False (void);
+solver_lbool solver_get_l_Undef (void);
+
+solver_lbool solver_value_Var (solver *s, solver_Var x);
+solver_lbool solver_value_Lit (solver *s, solver_Lit p);
+
+solver_lbool solver_modelValue_Var (solver *s, solver_Var x);
+solver_lbool solver_modelValue_Lit (solver *s, solver_Lit p);
+
+int solver_num_assigns (solver *s);
+int solver_num_clauses (solver *s);
+int solver_num_learnts (solver *s);
+int solver_num_vars (solver *s);
+int solver_num_freeVars (solver *s);
+
+int solver_conflict_len (solver *s);
+solver_Lit solver_conflict_nthLit (solver *s, int i);
+
+// Setters:
+
+void solver_set_verbosity (solver *s, int v);
+
+// Getters:
+
+int solver_num_conflicts (solver *s);
+
+/* TODO
+
+ // Mode of operation:
+ //
+ int verbosity;
+ double var_decay;
+ double clause_decay;
+ double random_var_freq;
+ double random_seed;
+ double restart_luby_start; // The factor with which the values of the luby sequence is multiplied to get the restart (default 100)
+ double restart_luby_inc; // The constant that the luby sequence uses powers of (default 2)
+ bool expensive_ccmin; // FIXME: describe.
+ bool rnd_pol; // FIXME: describe.
+
+ int restart_first; // The initial restart limit. (default 100)
+ double restart_inc; // The factor with which the restart limit is multiplied in each restart. (default 1.5)
+ double learntsize_factor; // The intitial limit for learnt clauses is a factor of the original clauses. (default 1 / 3)
+ double learntsize_inc; // The limit for learnt clauses is multiplied with this factor each restart. (default 1.1)
+
+ int learntsize_adjust_start_confl;
+ double learntsize_adjust_inc;
+
+ // Statistics: (read-only member variable)
+ //
+ uint64_t starts, decisions, rnd_decisions, propagations, conflicts;
+ uint64_t dec_vars, clauses_literals, learnts_literals, max_literals, tot_literals;
+*/
+
+#endif