summaryrefslogtreecommitdiffstats
path: root/src/proof
diff options
context:
space:
mode:
authorMathias Soeken <mathias.soeken@gmail.com>2017-02-22 19:00:28 -0800
committerMathias Soeken <mathias.soeken@gmail.com>2017-02-22 19:00:28 -0800
commit28e8e7f3e79d1391a2f3a31cefe3afe234aa3b8e (patch)
tree6b7962dc72653e3bf615c5901854774eca9d23c8 /src/proof
parent5af44731bff0061c724912cf76e86dddbb4f2c7a (diff)
parentdd8cc7e9a27e2bd962d612911c6fd9508c6c1e0d (diff)
downloadabc-28e8e7f3e79d1391a2f3a31cefe3afe234aa3b8e.tar.gz
abc-28e8e7f3e79d1391a2f3a31cefe3afe234aa3b8e.tar.bz2
abc-28e8e7f3e79d1391a2f3a31cefe3afe234aa3b8e.zip
Merged alanmi/abc into default
Diffstat (limited to 'src/proof')
-rw-r--r--src/proof/acec/acec.h27
-rw-r--r--src/proof/acec/acecBo.c216
-rw-r--r--src/proof/acec/acecCl.c390
-rw-r--r--src/proof/acec/acecCo.c2
-rw-r--r--src/proof/acec/acecCore.c509
-rw-r--r--src/proof/acec/acecInt.h37
-rw-r--r--src/proof/acec/acecMult.c617
-rw-r--r--src/proof/acec/acecNorm.c226
-rw-r--r--src/proof/acec/acecPa.c5
-rw-r--r--src/proof/acec/acecPool.c17
-rw-r--r--src/proof/acec/acecRe.c47
-rw-r--r--src/proof/acec/acecSt.c2
-rw-r--r--src/proof/acec/acecStruct.c271
-rw-r--r--src/proof/acec/acecTree.c783
-rw-r--r--src/proof/acec/acecUtil.c23
-rw-r--r--src/proof/acec/acecXor.c434
-rw-r--r--src/proof/acec/module.make7
-rw-r--r--src/proof/cec/cecCec.c9
-rw-r--r--src/proof/cec/cecSat.c1003
-rw-r--r--src/proof/cec/cecSimBack.c194
-rw-r--r--src/proof/cec/module.make1
-rw-r--r--src/proof/fra/fraCec.c6
-rw-r--r--src/proof/fra/fraSec.c4
-rw-r--r--src/proof/pdr/module.make4
-rw-r--r--src/proof/pdr/pdr.h9
-rw-r--r--src/proof/pdr/pdrCore.c502
-rw-r--r--src/proof/pdr/pdrIncr.c760
-rw-r--r--src/proof/pdr/pdrInt.h32
-rw-r--r--src/proof/pdr/pdrInv.c376
-rw-r--r--src/proof/pdr/pdrMan.c341
-rw-r--r--src/proof/pdr/pdrSat.c39
-rw-r--r--src/proof/pdr/pdrTsim.c134
-rw-r--r--src/proof/pdr/pdrTsim2.c550
-rw-r--r--src/proof/pdr/pdrUtil.c137
34 files changed, 7411 insertions, 303 deletions
diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h
index c61b4485..fcbd32df 100644
--- a/src/proof/acec/acec.h
+++ b/src/proof/acec/acec.h
@@ -38,6 +38,22 @@ ABC_NAMESPACE_HEADER_START
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
+// combinational equivalence checking parameters
+typedef struct Acec_ParCec_t_ Acec_ParCec_t;
+struct Acec_ParCec_t_
+{
+ int nBTLimit; // conflict limit at a node
+ int TimeLimit; // the runtime limit in seconds
+ int fMiter; // input circuit is a miter
+ int fDualOutput; // dual-output miter
+ int fTwoOutput; // two-output miter
+ int fBooth; // expecting Booth multiplier
+ int fSilent; // print no messages
+ int fVeryVerbose; // verbose stats
+ int fVerbose; // verbose stats
+ int iOutFail; // the number of failed output
+};
+
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -50,8 +66,11 @@ ABC_NAMESPACE_HEADER_START
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+/*=== acecCl.c ========================================================*/
+extern Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose );
/*=== acecCore.c ========================================================*/
-extern int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars );
+extern void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p );
+extern int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars );
/*=== acecFadds.c ========================================================*/
extern Vec_Int_t * Gia_ManDetectFullAdders( Gia_Man_t * p, int fVerbose, Vec_Int_t ** vCutsXor2 );
extern Vec_Int_t * Gia_ManDetectHalfAdders( Gia_Man_t * p, int fVerbose );
@@ -60,6 +79,12 @@ extern Vec_Int_t * Gia_PolynReorder( Gia_Man_t * pGia, int fVerbose, int fVery
extern Vec_Int_t * Gia_PolynFindOrder( Gia_Man_t * pGia, Vec_Int_t * vFadds, Vec_Int_t * vHadds, int fVerbose, int fVeryVerbose );
/*=== acecPolyn.c ========================================================*/
extern void Gia_PolynBuild( Gia_Man_t * pGia, Vec_Int_t * vOrder, int fSigned, int fVerbose, int fVeryVerbose );
+/*=== acecRe.c ========================================================*/
+extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
+extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
+extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
+/*=== acecTree.c ========================================================*/
+extern Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose );
ABC_NAMESPACE_HEADER_END
diff --git a/src/proof/acec/acecBo.c b/src/proof/acec/acecBo.c
new file mode 100644
index 00000000..9cddcd13
--- /dev/null
+++ b/src/proof/acec/acecBo.c
@@ -0,0 +1,216 @@
+/**CFile****************************************************************
+
+ FileName [acecBo.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Core procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecBo.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "acecInt.h"
+#include "misc/vec/vecWec.h"
+#include "misc/extra/extra.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_DetectBoothXorMux( Gia_Man_t * p, Gia_Obj_t * pMux, Gia_Obj_t * pXor, int pIns[3] )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ Gia_Obj_t * pDat0, * pDat1, * pCtrl;
+ if ( !Gia_ObjIsMuxType(pMux) || !Gia_ObjIsMuxType(pXor) )
+ return 0;
+ if ( !Gia_ObjRecognizeExor( pXor, &pFan0, &pFan1 ) )
+ return 0;
+ pFan0 = Gia_Regular(pFan0);
+ pFan1 = Gia_Regular(pFan1);
+ if ( Gia_ObjId(p, pFan0) > Gia_ObjId(p, pFan1) )
+ ABC_SWAP( Gia_Obj_t *, pFan0, pFan1 );
+ if ( !(pCtrl = Gia_ObjRecognizeMux( pMux, &pDat0, &pDat1 )) )
+ return 0;
+ pDat0 = Gia_Regular(pDat0);
+ pDat1 = Gia_Regular(pDat1);
+ pCtrl = Gia_Regular(pCtrl);
+ if ( !Gia_ObjIsAnd(pDat0) || !Gia_ObjIsAnd(pDat1) )
+ return 0;
+ if ( Gia_ObjFaninId0p(p, pDat0) != Gia_ObjFaninId0p(p, pDat1) ||
+ Gia_ObjFaninId1p(p, pDat0) != Gia_ObjFaninId1p(p, pDat1) )
+ return 0;
+ if ( Gia_ObjFaninId0p(p, pDat0) != Gia_ObjId(p, pFan0) ||
+ Gia_ObjFaninId1p(p, pDat0) != Gia_ObjId(p, pFan1) )
+ return 0;
+ pIns[0] = Gia_ObjId(p, pFan0);
+ pIns[1] = Gia_ObjId(p, pFan1);
+ pIns[2] = Gia_ObjId(p, pCtrl);
+ return 1;
+}
+int Acec_DetectBoothXorFanin( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ //int Id = Gia_ObjId(p, pObj);
+ if ( !Gia_ObjIsAnd(pObj) )
+ return 0;
+ if ( !Gia_ObjFaninC0(pObj) || !Gia_ObjFaninC1(pObj) )
+ return 0;
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( !Gia_ObjIsAnd(pFan0) || !Gia_ObjIsAnd(pFan1) )
+ return 0;
+ if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin0(pFan0), Gia_ObjFanin0(pFan1), pIns) )
+ {
+ pIns[3] = Gia_ObjId(p, Gia_ObjFanin1(pFan0));
+ pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pFan1));
+ return 1;
+ }
+ if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin0(pFan0), Gia_ObjFanin1(pFan1), pIns) )
+ {
+ pIns[3] = Gia_ObjId(p, Gia_ObjFanin1(pFan0));
+ pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pFan1));
+ return 1;
+ }
+ if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin1(pFan0), Gia_ObjFanin0(pFan1), pIns) )
+ {
+ pIns[3] = Gia_ObjId(p, Gia_ObjFanin0(pFan0));
+ pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pFan1));
+ return 1;
+ }
+ if ( Acec_DetectBoothXorMux(p, Gia_ObjFanin1(pFan0), Gia_ObjFanin1(pFan1), pIns) )
+ {
+ pIns[3] = Gia_ObjId(p, Gia_ObjFanin0(pFan0));
+ pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pFan1));
+ return 1;
+ }
+ return 0;
+}
+int Acec_DetectBoothOne( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ if ( !Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) )
+ return 0;
+ pFan0 = Gia_Regular(pFan0);
+ pFan1 = Gia_Regular(pFan1);
+ if ( Acec_DetectBoothXorFanin( p, pFan0, pIns ) && pIns[2] == Gia_ObjId(p, pFan1) )
+ return 1;
+ if ( Acec_DetectBoothXorFanin( p, pFan1, pIns ) && pIns[2] == Gia_ObjId(p, pFan0) )
+ return 1;
+ return 0;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_DetectBoothTwoXor( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ if ( !Gia_ObjIsAnd(pObj) )
+ return 0;
+ if ( Gia_ObjRecognizeExor( Gia_ObjFanin0(pObj), &pFan0, &pFan1 ) )
+ {
+ pIns[0] = Gia_ObjId(p, Gia_Regular(pFan0));
+ pIns[1] = Gia_ObjId(p, Gia_Regular(pFan1));
+ pIns[2] = -1;
+ pIns[3] = 0;
+ pIns[4] = Gia_ObjId(p, Gia_ObjFanin1(pObj));
+ return 1;
+ }
+ if ( Gia_ObjRecognizeExor( Gia_ObjFanin1(pObj), &pFan0, &pFan1 ) )
+ {
+ pIns[0] = Gia_ObjId(p, Gia_Regular(pFan0));
+ pIns[1] = Gia_ObjId(p, Gia_Regular(pFan1));
+ pIns[2] = -1;
+ pIns[3] = 0;
+ pIns[4] = Gia_ObjId(p, Gia_ObjFanin0(pObj));
+ return 1;
+ }
+ return 0;
+}
+int Acec_DetectBoothTwo( Gia_Man_t * p, Gia_Obj_t * pObj, int pIns[5] )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ if ( !Gia_ObjRecognizeExor( pObj, &pFan0, &pFan1 ) )
+ return 0;
+ pFan0 = Gia_Regular(pFan0);
+ pFan1 = Gia_Regular(pFan1);
+ if ( Acec_DetectBoothTwoXor( p, pFan0, pIns ) )
+ {
+ pIns[2] = Gia_ObjId(p, pFan1);
+ return 1;
+ }
+ if ( Acec_DetectBoothTwoXor( p, pFan1, pIns ) )
+ {
+ pIns[2] = Gia_ObjId(p, pFan0);
+ return 1;
+ }
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_DetectBoothTest( Gia_Man_t * p )
+{
+ Gia_Obj_t * pObj;
+ int i, pIns[5];
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Acec_DetectBoothOne(p, pObj, pIns) && !Acec_DetectBoothTwo(p, pObj, pIns) )
+ continue;
+ printf( "obj = %4d : b0 = %4d b1 = %4d b2 = %4d a0 = %4d a1 = %4d\n",
+ i, pIns[0], pIns[1], pIns[2], pIns[3], pIns[4] );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/acecCl.c b/src/proof/acec/acecCl.c
index 32be3b30..6185677b 100644
--- a/src/proof/acec/acecCl.c
+++ b/src/proof/acec/acecCl.c
@@ -45,6 +45,396 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
+void Acec_ManDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, int Node, Vec_Int_t * vMirrors )
+{
+ Gia_Obj_t * pObj;
+ int Obj = Node;
+ if ( Vec_IntEntry(vMirrors, Node) >= 0 )
+ Obj = Abc_Lit2Var( Vec_IntEntry(vMirrors, Node) );
+ pObj = Gia_ManObj( p, Obj );
+ if ( !~pObj->Value )
+ {
+ assert( Gia_ObjIsAnd(pObj) );
+ Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId0(pObj, Obj), vMirrors );
+ Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId1(pObj, Obj), vMirrors );
+ if ( Gia_ObjIsXor(pObj) )
+ pObj->Value = Gia_ManAppendXorReal( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ else
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ }
+ // set the original node as well
+ if ( Obj != Node )
+ Gia_ManObj(p, Node)->Value = Abc_LitNotCond( pObj->Value, Abc_LitIsCompl(Vec_IntEntry(vMirrors, Node)) );
+}
+Gia_Man_t * Acec_ManDerive( Gia_Man_t * p, Vec_Int_t * vMirrors )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ int i;
+ assert( p->pMuxes == NULL );
+ Gia_ManFillValue( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManHashAlloc( pNew );
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManForEachCo( p, pObj, i )
+ Acec_ManDerive_rec( pNew, p, Gia_ObjFaninId0p(p, pObj), vMirrors );
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManHashStop( pNew );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_CollectXorTops( Gia_Man_t * p )
+{
+ Vec_Int_t * vRootXorSet = Vec_IntAlloc( Gia_ManCoNum(p) );
+ Gia_Obj_t * pObj, * pFan0, * pFan1, * pFan00, * pFan01, * pFan10, * pFan11;
+ int i, fXor0, fXor1, fFirstXor = 0;
+ Gia_ManForEachCoDriver( p, pObj, i )
+ {
+ if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
+ {
+ if ( fFirstXor )
+ {
+ printf( "XORs do not form a continuous sequence\n" );
+ Vec_IntFreeP( &vRootXorSet );
+ break;
+ }
+ continue;
+ }
+ fFirstXor = 1;
+ fXor0 = Gia_ObjRecognizeExor(Gia_Regular(pFan0), &pFan00, &pFan01);
+ fXor1 = Gia_ObjRecognizeExor(Gia_Regular(pFan1), &pFan10, &pFan11);
+ if ( fXor0 == fXor1 )
+ {
+ printf( "Both inputs of top level XOR have XOR/non-XOR\n" );
+ Vec_IntFreeP( &vRootXorSet );
+ break;
+ }
+ Vec_IntPush( vRootXorSet, Gia_ObjId(p, pObj) );
+ Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan0)) : Gia_ObjId(p, Gia_Regular(pFan1)) );
+ Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan10)) : Gia_ObjId(p, Gia_Regular(pFan00)) );
+ Vec_IntPush( vRootXorSet, fXor1 ? Gia_ObjId(p, Gia_Regular(pFan11)) : Gia_ObjId(p, Gia_Regular(pFan01)) );
+ }
+ for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ )
+ {
+ printf( "%2d : ", i );
+ printf( "%4d <- ", Vec_IntEntry(vRootXorSet, 4*i) );
+ printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+1) );
+ printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+2) );
+ printf( "%4d ", Vec_IntEntry(vRootXorSet, 4*i+3) );
+ printf( "\n" );
+ }
+ return vRootXorSet;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_DetectLitPolarity( Gia_Man_t * p, int Node, int Leaf )
+{
+ Gia_Obj_t * pNode;
+ int Lit0, Lit1;
+ if ( Node < Leaf )
+ return -1;
+ if ( Node == Leaf )
+ return Abc_Var2Lit(Node, 0);
+ pNode = Gia_ManObj( p, Node );
+ Lit0 = Acec_DetectLitPolarity( p, Gia_ObjFaninId0(pNode, Node), Leaf );
+ Lit1 = Acec_DetectLitPolarity( p, Gia_ObjFaninId1(pNode, Node), Leaf );
+ Lit0 = Lit0 == -1 ? Lit0 : Abc_LitNotCond( Lit0, Gia_ObjFaninC0(pNode) );
+ Lit1 = Lit1 == -1 ? Lit1 : Abc_LitNotCond( Lit1, Gia_ObjFaninC1(pNode) );
+ if ( Lit0 == -1 && Lit1 == -1 )
+ return -1;
+ assert( Lit0 != -1 || Lit1 != -1 );
+ if ( Lit0 != -1 && Lit1 != -1 )
+ {
+ assert( Lit0 == Lit1 );
+ printf( "Problem for leaf %d\n", Leaf );
+ return Lit0;
+ }
+ return Lit0 != -1 ? Lit0 : Lit1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_DetectComputeSuppOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp, Vec_Int_t * vNods )
+{
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ if ( pObj->fMark0 )
+ {
+ Vec_IntPush( vSupp, Gia_ObjId(p, pObj) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Acec_DetectComputeSuppOne_rec( p, Gia_ObjFanin0(pObj), vSupp, vNods );
+ Acec_DetectComputeSuppOne_rec( p, Gia_ObjFanin1(pObj), vSupp, vNods );
+ Vec_IntPush( vNods, Gia_ObjId(p, pObj) );
+}
+void Acec_DetectComputeSupports( Gia_Man_t * p, Vec_Int_t * vRootXorSet )
+{
+ Vec_Int_t * vNods = Vec_IntAlloc( 100 );
+ Vec_Int_t * vPols = Vec_IntAlloc( 100 );
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 ); int i, k, Node, Pol;
+ for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ )
+ {
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 1;
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+2) )->fMark0 = 1;
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+3) )->fMark0 = 1;
+ }
+ for ( i = 1; 4*i < Vec_IntSize(vRootXorSet); i++ )
+ {
+ Vec_IntClear( vSupp );
+ Gia_ManIncrementTravId( p );
+
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 0;
+ Acec_DetectComputeSuppOne_rec( p, Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) ), vSupp, vNods );
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 1;
+
+ Vec_IntSort( vSupp, 0 );
+
+ printf( "Out %4d : %4d \n", i, Vec_IntEntry(vRootXorSet, 4*i+1) );
+ Vec_IntPrint( vSupp );
+
+ printf( "Cone:\n" );
+ Vec_IntForEachEntry( vNods, Node, k )
+ Gia_ObjPrint( p, Gia_ManObj(p, Node) );
+
+
+ Vec_IntClear( vPols );
+ Vec_IntForEachEntry( vSupp, Node, k )
+ Vec_IntPush( vPols, Acec_DetectLitPolarity(p, Vec_IntEntry(vRootXorSet, 4*i+1), Node) );
+
+ Vec_IntForEachEntryTwo( vSupp, vPols, Node, Pol, k )
+ printf( "%d(%d) ", Node, Abc_LitIsCompl(Pol) );
+
+ printf( "\n" );
+
+ Vec_IntPrint( vSupp );
+ }
+ for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ )
+ {
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+1) )->fMark0 = 0;
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+2) )->fMark0 = 0;
+ Gia_ManObj( p, Vec_IntEntry(vRootXorSet, 4*i+3) )->fMark0 = 0;
+ }
+ Vec_IntFree( vSupp );
+ Vec_IntFree( vPols );
+ Vec_IntFree( vNods );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Acec_DetectXorBuildNew( Gia_Man_t * p, Vec_Int_t * vRootXorSet )
+{
+ Gia_Man_t * pNew;
+ int i, k, iOr1, iAnd1, iAnd2, pLits[3]; // carry, in1, in2
+ Vec_Int_t * vMirrors = Vec_IntStart( Gia_ManObjNum(p) );
+ for ( i = 0; 4*i < Vec_IntSize(vRootXorSet); i++ )
+ {
+ pLits[0] = Acec_DetectLitPolarity( p, Vec_IntEntry(vRootXorSet, 4*i), Vec_IntEntry(vRootXorSet, 4*i+1) );
+ // get polarity of two new ones
+ for ( k = 1; k < 3; k++ )
+ pLits[k] = Acec_DetectLitPolarity( p, Vec_IntEntry(vRootXorSet, 4*i), Vec_IntEntry(vRootXorSet, 4*i+k+1) );
+ // create the gate
+ iOr1 = Gia_ManAppendOr( p, pLits[1], pLits[2] );
+ iAnd1 = Gia_ManAppendAnd( p, pLits[0], iOr1 );
+ iAnd2 = Gia_ManAppendAnd( p, pLits[1], pLits[2] );
+ pLits[0] = Gia_ManAppendOr( p, iAnd1, iAnd2 );
+ Vec_IntWriteEntry( vMirrors, Vec_IntEntry(vRootXorSet, 4*i+1), pLits[0] );
+ }
+ // remap the AIG using map
+ pNew = Acec_ManDerive( p, vMirrors );
+ Vec_IntFree( vMirrors );
+ return pNew;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Acec_DetectAdditional( Gia_Man_t * p, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew;
+ Vec_Int_t * vRootXorSet;
+// Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 );
+
+ //Ree_ManPrintAdders( vAdds, 1 );
+// printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 );
+// Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ clk = Abc_Clock();
+ vRootXorSet = Acec_CollectXorTops( p );
+ if ( vRootXorSet )
+ {
+ Acec_DetectComputeSupports( p, vRootXorSet );
+
+ pNew = Acec_DetectXorBuildNew( p, vRootXorSet );
+ Vec_IntFree( vRootXorSet );
+ }
+ else
+ pNew = Gia_ManDup( p );
+
+ printf( "Detected %d top XORs. ", Vec_IntSize(vRootXorSet)/4 );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+// Vec_IntFree( vXors );
+// Vec_IntFree( vAdds );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_RewriteTop( Gia_Man_t * p, Acec_Box_t * pBox )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( Gia_ManCoNum(p) + 1 );
+ Vec_Int_t * vLevel;
+ int i, k, iStart, iLit, Driver, Count = 0;
+ // determine how much to shift
+ Driver = Gia_ObjFaninId0p( p, Gia_ManCo(p, 0) );
+ Vec_WecForEachLevel( pBox->vRootLits, vLevel, iStart )
+ if ( Abc_Lit2Var(Vec_IntEntry(vLevel,0)) == Driver )
+ break;
+ assert( iStart < Gia_ManCoNum(p) );
+ //Vec_WecPrintLits( pBox->vRootLits );
+ Vec_WecForEachLevelStart( pBox->vRootLits, vLevel, i, iStart )
+ {
+ int In[3] = {0}, Out[2];
+ assert( Vec_IntSize(vLevel) > 0 );
+ assert( Vec_IntSize(vLevel) <= 3 );
+ if ( Vec_IntSize(vLevel) == 1 )
+ {
+ Vec_IntPush( vRes, Vec_IntEntry(vLevel, 0) );
+ continue;
+ }
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ In[k] = iLit;
+ Acec_InsertFadd( p, In, Out );
+ Vec_IntPush( vRes, Out[0] );
+ if ( i+1 < Vec_WecSize(pBox->vRootLits) )
+ Vec_IntPush( Vec_WecEntry(pBox->vRootLits, i+1), Out[1] );
+ else
+ Vec_IntPush( Vec_WecPushLevel(pBox->vRootLits), Out[1] );
+ Count++;
+ }
+ assert( Vec_IntSize(vRes) >= Gia_ManCoNum(p) );
+ Vec_IntShrink( vRes, Gia_ManCoNum(p) );
+ printf( "Added %d adders for replace CLAs. ", Count );
+ return vRes;
+}
+Gia_Man_t * Acec_RewriteReplace( Gia_Man_t * p, Vec_Int_t * vRes )
+{
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj; int i;
+ assert( Gia_ManCoNum(p) == Vec_IntSize(vRes) );
+ // create new manager
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManFillValue( p );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pNew);
+ Gia_ManForEachAnd( p, pObj, i )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ {
+ int iLit = Vec_IntEntry( vRes, i );
+ Gia_Obj_t * pRepr = Gia_ManObj( p, Abc_Lit2Var(iLit) );
+ pObj->Value = Gia_ManAppendCo( pNew, pRepr->Value );
+ }
+ // set correct phase
+ Gia_ManSetPhase( p );
+ Gia_ManSetPhase( pNew );
+ Gia_ManForEachCo( pNew, pObj, i )
+ if ( Gia_ObjPhase(pObj) != Gia_ObjPhase(Gia_ManCo(p, i)) )
+ Gia_ObjFlipFaninC0( pObj );
+ // remove dangling nodes
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ return pNew;
+}
+Gia_Man_t * Acec_ManDecla( Gia_Man_t * pGia, int fBooth, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew = NULL;
+ Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG(pGia) : NULL;
+ Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose );
+ Vec_Int_t * vResult;
+ Vec_BitFreeP( &vIgnore );
+ if ( pBox == NULL ) // cannot match
+ {
+ printf( "Cannot find arithmetic boxes.\n" );
+ return Gia_ManDup( pGia );
+ }
+ vResult = Acec_RewriteTop( pGia, pBox );
+ Acec_BoxFreeP( &pBox );
+ pNew = Acec_RewriteReplace( pGia, vResult );
+ Vec_IntFree( vResult );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ return pNew;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/proof/acec/acecCo.c b/src/proof/acec/acecCo.c
index 1e8ed7bb..a997eb03 100644
--- a/src/proof/acec/acecCo.c
+++ b/src/proof/acec/acecCo.c
@@ -109,7 +109,7 @@ Vec_Int_t * Gia_PolynCoreOrder_int( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Wec
{
Vec_Int_t * vOrder = Vec_IntAlloc( 1000 );
Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(pGia) );
- int i, k, Index, Driver, Entry1, Entry2 = -1;
+ int i, k, Index = -1, Driver, Entry1, Entry2 = -1;
// mark roots
Vec_IntForEachEntry( vRoots, Driver, i )
Vec_BitWriteEntry( vIsRoot, Driver, 1 );
diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c
index ac7ee67b..1a575fbe 100644
--- a/src/proof/acec/acecCore.c
+++ b/src/proof/acec/acecCore.c
@@ -19,6 +19,9 @@
***********************************************************************/
#include "acecInt.h"
+#include "proof/cec/cec.h"
+#include "misc/util/utilTruth.h"
+#include "misc/extra/extra.h"
ABC_NAMESPACE_IMPL_START
@@ -27,12 +30,452 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+#define TRUTH_UNUSED 0x1234567812345678
+
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
+ Synopsis [This procedure sets default parameters.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_ManCecSetDefaultParams( Acec_ParCec_t * p )
+{
+ memset( p, 0, sizeof(Acec_ParCec_t) );
+ p->nBTLimit = 1000; // conflict limit at a node
+ p->TimeLimit = 0; // the runtime limit in seconds
+ p->fMiter = 0; // input circuit is a miter
+ p->fDualOutput = 0; // dual-output miter
+ p->fTwoOutput = 0; // two-output miter
+ p->fSilent = 0; // print no messages
+ p->fVeryVerbose = 0; // verbose stats
+ p->fVerbose = 0; // verbose stats
+ p->iOutFail = -1; // the number of failed output
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_VerifyClasses( Gia_Man_t * p, Vec_Wec_t * vLits, Vec_Wec_t * vReprs )
+{
+ Vec_Ptr_t * vFunc = Vec_PtrAlloc( Vec_WecSize(vLits) );
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel;
+ int i, j, k, Entry, Entry2, nOvers = 0, nErrors = 0;
+ Vec_WecForEachLevel( vLits, vLevel, i )
+ {
+ Vec_Wrd_t * vTruths = Vec_WrdAlloc( Vec_IntSize(vLevel) );
+ Vec_IntForEachEntry( vLevel, Entry, k )
+ {
+ word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp );
+ if ( Vec_IntSize(vSupp) > 6 )
+ {
+ nOvers++;
+ Vec_WrdPush( vTruths, TRUTH_UNUSED );
+ continue;
+ }
+ vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize );
+ if ( Vec_IntSize(vSupp) > 5 )
+ {
+ nOvers++;
+ Vec_WrdPush( vTruths, TRUTH_UNUSED );
+ continue;
+ }
+ Vec_WrdPush( vTruths, Truth );
+ }
+ Vec_PtrPush( vFunc, vTruths );
+ }
+ if ( nOvers )
+ printf( "Detected %d oversize support nodes.\n", nOvers );
+ Vec_IntFree( vSupp );
+ Vec_WrdFree( vTemp );
+ // verify the classes
+ Vec_WecForEachLevel( vReprs, vLevel, i )
+ {
+ Vec_Wrd_t * vTruths = (Vec_Wrd_t *)Vec_PtrEntry( vFunc, i );
+ Vec_IntForEachEntry( vLevel, Entry, k )
+ Vec_IntForEachEntryStart( vLevel, Entry2, j, k+1 )
+ {
+ word Truth = Vec_WrdEntry( vTruths, k );
+ word Truth2 = Vec_WrdEntry( vTruths, j );
+ if ( Entry == Entry2 )
+ {
+ nErrors++;
+ if ( Truth != Truth2 && Truth != TRUTH_UNUSED && Truth2 != TRUTH_UNUSED )
+ printf( "Rank %d: Lit %d and %d do not pass verification.\n", i, k, j );
+ }
+ if ( Entry == Abc_LitNot(Entry2) )
+ {
+ nErrors++;
+ if ( Truth != ~Truth2 && Truth != TRUTH_UNUSED && Truth2 != TRUTH_UNUSED )
+ printf( "Rank %d: Lit %d and %d do not pass verification.\n", i, k, j );
+ }
+ }
+ }
+ if ( nErrors )
+ printf( "Total errors in equivalence classes = %d.\n", nErrors );
+ Vec_VecFree( (Vec_Vec_t *)vFunc );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Acec_CommonStart( Gia_Man_t * pBase, Gia_Man_t * pAdd )
+{
+ Gia_Obj_t * pObj;
+ int i;
+ Gia_ManFillValue( pAdd );
+ Gia_ManConst0(pAdd)->Value = 0;
+ if ( pBase == NULL )
+ {
+ pBase = Gia_ManStart( Gia_ManObjNum(pAdd) );
+ pBase->pName = Abc_UtilStrsav( pAdd->pName );
+ pBase->pSpec = Abc_UtilStrsav( pAdd->pSpec );
+ Gia_ManForEachCi( pAdd, pObj, i )
+ pObj->Value = Gia_ManAppendCi(pBase);
+ Gia_ManHashAlloc( pBase );
+ }
+ else
+ {
+ assert( Gia_ManCiNum(pBase) == Gia_ManCiNum(pAdd) );
+ Gia_ManForEachCi( pAdd, pObj, i )
+ pObj->Value = Gia_Obj2Lit( pBase, Gia_ManCi(pBase, i) );
+ }
+ Gia_ManForEachAnd( pAdd, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pBase, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ return pBase;
+}
+void Acec_CommonFinish( Gia_Man_t * pBase )
+{
+ int Id;
+ Gia_ManCreateRefs( pBase );
+ Gia_ManForEachAndId( pBase, Id )
+ if ( Gia_ObjRefNumId(pBase, Id) == 0 )
+ Gia_ManAppendCo( pBase, Abc_Var2Lit(Id,0) );
+}
+Vec_Int_t * Acec_CountRemap( Gia_Man_t * pAdd, Gia_Man_t * pBase )
+{
+ Gia_Obj_t * pObj; int i;
+ Vec_Int_t * vMapNew = Vec_IntStartFull( Gia_ManObjNum(pAdd) );
+ Gia_ManSetPhase( pAdd );
+ Vec_IntWriteEntry( vMapNew, 0, 0 );
+ Gia_ManForEachCand( pAdd, pObj, i )
+ {
+ int iObjBase = Abc_Lit2Var(pObj->Value);
+ Gia_Obj_t * pObjBase = Gia_ManObj( pBase, iObjBase );
+ int iObjRepr = Abc_Lit2Var(pObjBase->Value);
+ Vec_IntWriteEntry( vMapNew, i, Abc_Var2Lit(iObjRepr, Gia_ObjPhase(pObj)) );
+ }
+ return vMapNew;
+}
+void Acec_ComputeEquivClasses( Gia_Man_t * pOne, Gia_Man_t * pTwo, Vec_Int_t ** pvMap1, Vec_Int_t ** pvMap2 )
+{
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pBase, * pRepr;
+ pBase = Acec_CommonStart( NULL, pOne );
+ pBase = Acec_CommonStart( pBase, pTwo );
+ Acec_CommonFinish( pBase );
+ //Gia_ManShow( pBase, NULL, 0, 0, 0 );
+ pRepr = Gia_ManComputeGiaEquivs( pBase, 100, 0 );
+ *pvMap1 = Acec_CountRemap( pOne, pBase );
+ *pvMap2 = Acec_CountRemap( pTwo, pBase );
+ Gia_ManStop( pBase );
+ Gia_ManStop( pRepr );
+ printf( "Finished computing equivalent nodes. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+void Acec_MatchBoxesSort( int * pArray, int nSize, int * pCostLits )
+{
+ int i, j, best_i;
+ for ( i = 0; i < nSize-1; i++ )
+ {
+ best_i = i;
+ for ( j = i+1; j < nSize; j++ )
+ if ( Abc_Lit2LitL(pCostLits, pArray[j]) > Abc_Lit2LitL(pCostLits, pArray[best_i]) )
+ best_i = j;
+ ABC_SWAP( int, pArray[i], pArray[best_i] );
+ }
+}
+void Acec_MatchPrintEquivLits( Gia_Man_t * p, Vec_Wec_t * vLits, int * pCostLits, int fVerbose )
+{
+ Vec_Int_t * vSupp;
+ Vec_Wrd_t * vTemp;
+ Vec_Int_t * vLevel;
+ int i, k, Entry;
+ printf( "Leaf literals and their classes:\n" );
+ Vec_WecForEachLevel( vLits, vLevel, i )
+ {
+ if ( Vec_IntSize(vLevel) == 0 )
+ continue;
+ printf( "Rank %2d : %2d ", i, Vec_IntSize(vLevel) );
+ Vec_IntForEachEntry( vLevel, Entry, k )
+ printf( "%s%d(%d) ", Abc_LitIsCompl(Entry) ? "-":"+", Abc_Lit2Var(Entry), Abc_Lit2LitL(pCostLits, Entry) );
+ printf( "\n" );
+ }
+ if ( !fVerbose )
+ return;
+ vSupp = Vec_IntAlloc( 100 );
+ vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
+ Vec_WecForEachLevel( vLits, vLevel, i )
+ {
+ //if ( i != 20 )
+ // continue;
+ if ( Vec_IntSize(vLevel) == 0 )
+ continue;
+ Vec_IntForEachEntry( vLevel, Entry, k )
+ {
+ word Truth = Gia_ObjComputeTruth6Cis( p, Entry, vSupp, vTemp );
+/*
+ {
+ int iObj = Abc_Lit2Var(Entry);
+ Gia_Man_t * pGia0 = Gia_ManDupAndCones( p, &iObj, 1, 1 );
+ Gia_ManShow( pGia0, NULL, 0, 0, 0 );
+ Gia_ManStop( pGia0 );
+ }
+*/
+ printf( "Rank = %4d : ", i );
+ printf( "Obj = %4d ", Abc_Lit2Var(Entry) );
+ if ( Vec_IntSize(vSupp) > 6 )
+ {
+ printf( "Supp = %d.\n", Vec_IntSize(vSupp) );
+ continue;
+ }
+ vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize );
+ if ( Vec_IntSize(vSupp) > 5 )
+ {
+ printf( "Supp = %d.\n", Vec_IntSize(vSupp) );
+ continue;
+ }
+ Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
+ if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
+ if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
+ if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
+ printf( " " );
+ Vec_IntPrint( vSupp );
+ }
+ printf( "\n" );
+ }
+ Vec_IntFree( vSupp );
+ Vec_WrdFree( vTemp );
+}
+Vec_Wec_t * Acec_MatchCopy( Vec_Wec_t * vLits, Vec_Int_t * vMap )
+{
+ Vec_Wec_t * vRes = Vec_WecStart( Vec_WecSize(vLits) );
+ Vec_Int_t * vLevel; int i, k, iLit;
+ Vec_WecForEachLevel( vLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ Vec_WecPush( vRes, i, Abc_Lit2LitL(Vec_IntArray(vMap), iLit) );
+ return vRes;
+}
+int Acec_MatchCountCommon( Vec_Wec_t * vLits1, Vec_Wec_t * vLits2, int Shift )
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 100 );
+ Vec_Int_t * vLevel1, * vLevel2;
+ int i, nCommon = 0;
+ Vec_WecForEachLevel( vLits1, vLevel1, i )
+ {
+ if ( i+Shift < 0 || i+Shift >= Vec_WecSize(vLits2) )
+ continue;
+ vLevel2 = Vec_WecEntry( vLits2, i+Shift );
+ nCommon += Vec_IntTwoFindCommonReverse( vLevel1, vLevel2, vRes );
+ }
+ Vec_IntFree( vRes );
+ return nCommon;
+}
+void Vec_IntInsertOrder( Vec_Int_t * vLits, Vec_Int_t * vClasses, int Lit, int Class )
+{
+ int i;
+ for ( i = Vec_IntSize(vClasses)-1; i >= 0; i-- )
+ if ( Vec_IntEntry(vClasses,i) >= Class )
+ break;
+ Vec_IntInsert( vLits, i+1, Lit );
+ Vec_IntInsert( vClasses, i+1, Class );
+}
+void Acec_MoveDuplicates( Vec_Wec_t * vLits, Vec_Wec_t * vClasses )
+{
+ Vec_Int_t * vLevel1, * vLevel2;
+ int i, k, Prev, This, Entry, Counter = 0;
+ Vec_WecForEachLevel( vLits, vLevel1, i )
+ {
+ if ( i == Vec_WecSize(vLits) - 1 )
+ break;
+ vLevel2 = Vec_WecEntry(vClasses, i);
+ assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) );
+ Prev = -1;
+ Vec_IntForEachEntry( vLevel2, This, k )
+ {
+ if ( Prev != This )
+ {
+ Prev = This;
+ continue;
+ }
+ Prev = -1;
+ Entry = Vec_IntEntry( vLevel1, k );
+
+ Vec_IntDrop( vLevel1, k );
+ Vec_IntDrop( vLevel2, k-- );
+
+ Vec_IntDrop( vLevel1, k );
+ Vec_IntDrop( vLevel2, k-- );
+
+ Vec_IntInsertOrder( Vec_WecEntry(vLits, i+1), Vec_WecEntry(vClasses, i+1), Entry, This );
+
+ assert( Vec_IntSize(vLevel1) == Vec_IntSize(vLevel2) );
+ assert( Vec_IntSize(Vec_WecEntry(vLits, i+1)) == Vec_IntSize(Vec_WecEntry(vClasses, i+1)) );
+ Counter++;
+ }
+ }
+ printf( "Moved %d pairs of PPs to normalize the matrix.\n", Counter );
+}
+
+void Acec_MatchCheckShift( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Vec_Wec_t * vLits0, Vec_Wec_t * vLits1, Vec_Int_t * vMap0, Vec_Int_t * vMap1, Vec_Wec_t * vRoots0, Vec_Wec_t * vRoots1 )
+{
+ Vec_Wec_t * vRes0 = Acec_MatchCopy( vLits0, vMap0 );
+ Vec_Wec_t * vRes1 = Acec_MatchCopy( vLits1, vMap1 );
+ int nCommon = Acec_MatchCountCommon( vRes0, vRes1, 0 );
+ int nCommonPlus = Acec_MatchCountCommon( vRes0, vRes1, 1 );
+ int nCommonMinus = Acec_MatchCountCommon( vRes0, vRes1, -1 );
+ if ( nCommonPlus >= nCommonMinus && nCommonPlus > nCommon )
+ {
+ Vec_WecInsertLevel( vLits0, 0 );
+ Vec_WecInsertLevel( vRoots0, 0 );
+ Vec_WecInsertLevel( vRes0, 0 );
+ printf( "Shifted one level up.\n" );
+ }
+ else if ( nCommonMinus > nCommonPlus && nCommonMinus > nCommon )
+ {
+ Vec_WecInsertLevel( vLits1, 0 );
+ Vec_WecInsertLevel( vRoots1, 0 );
+ Vec_WecInsertLevel( vRes1, 0 );
+ printf( "Shifted one level down.\n" );
+ }
+ Acec_MoveDuplicates( vLits0, vRes0 );
+ Acec_MoveDuplicates( vLits1, vRes1 );
+
+ //Vec_WecPrintLits( vLits1 );
+ //printf( "Input literals:\n" );
+ //Vec_WecPrintLits( vLits0 );
+ //printf( "Equiv classes:\n" );
+ //Vec_WecPrintLits( vRes0 );
+ //printf( "Input literals:\n" );
+ //Vec_WecPrintLits( vLits1 );
+ //printf( "Equiv classes:\n" );
+ //Vec_WecPrintLits( vRes1 );
+ //Acec_VerifyClasses( pGia0, vLits0, vRes0 );
+ //Acec_VerifyClasses( pGia1, vLits1, vRes1 );
+ Vec_WecFree( vRes0 );
+ Vec_WecFree( vRes1 );
+}
+int Acec_MatchBoxes( Acec_Box_t * pBox0, Acec_Box_t * pBox1 )
+{
+ Vec_Int_t * vMap0, * vMap1, * vLevel;
+ int i, nSize, nTotal;
+ Acec_ComputeEquivClasses( pBox0->pGia, pBox1->pGia, &vMap0, &vMap1 );
+ // sort nodes in the classes by their equivalences
+ Vec_WecForEachLevel( pBox0->vLeafLits, vLevel, i )
+ Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap0) );
+ Vec_WecForEachLevel( pBox1->vLeafLits, vLevel, i )
+ Acec_MatchBoxesSort( Vec_IntArray(vLevel), Vec_IntSize(vLevel), Vec_IntArray(vMap1) );
+ Acec_MatchCheckShift( pBox0->pGia, pBox1->pGia, pBox0->vLeafLits, pBox1->vLeafLits, vMap0, vMap1, pBox0->vRootLits, pBox1->vRootLits );
+
+ //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vLeafLits, Vec_IntArray(vMap0), 0 );
+ //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vLeafLits, Vec_IntArray(vMap1), 0 );
+ //printf( "Outputs:\n" );
+ //Vec_WecPrintLits( pBox0->vRootLits );
+ //printf( "Outputs:\n" );
+ //Vec_WecPrintLits( pBox1->vRootLits );
+
+ // reorder nodes to have the same order
+ assert( pBox0->vShared == NULL );
+ assert( pBox1->vShared == NULL );
+ pBox0->vShared = Vec_WecStart( Vec_WecSize(pBox0->vLeafLits) );
+ pBox1->vShared = Vec_WecStart( Vec_WecSize(pBox1->vLeafLits) );
+ pBox0->vUnique = Vec_WecStart( Vec_WecSize(pBox0->vLeafLits) );
+ pBox1->vUnique = Vec_WecStart( Vec_WecSize(pBox1->vLeafLits) );
+ nSize = Abc_MinInt( Vec_WecSize(pBox0->vLeafLits), Vec_WecSize(pBox1->vLeafLits) );
+ Vec_WecForEachLevelStart( pBox0->vLeafLits, vLevel, i, nSize )
+ Vec_IntAppend( Vec_WecEntry(pBox0->vUnique, i), vLevel );
+ Vec_WecForEachLevelStart( pBox1->vLeafLits, vLevel, i, nSize )
+ Vec_IntAppend( Vec_WecEntry(pBox1->vUnique, i), vLevel );
+ for ( i = 0; i < nSize; i++ )
+ {
+ Vec_Int_t * vShared0 = Vec_WecEntry( pBox0->vShared, i );
+ Vec_Int_t * vShared1 = Vec_WecEntry( pBox1->vShared, i );
+ Vec_Int_t * vUnique0 = Vec_WecEntry( pBox0->vUnique, i );
+ Vec_Int_t * vUnique1 = Vec_WecEntry( pBox1->vUnique, i );
+
+ Vec_Int_t * vLevel0 = Vec_WecEntry( pBox0->vLeafLits, i );
+ Vec_Int_t * vLevel1 = Vec_WecEntry( pBox1->vLeafLits, i );
+ int * pBeg0 = Vec_IntArray(vLevel0);
+ int * pBeg1 = Vec_IntArray(vLevel1);
+ int * pEnd0 = Vec_IntLimit(vLevel0);
+ int * pEnd1 = Vec_IntLimit(vLevel1);
+ while ( pBeg0 < pEnd0 && pBeg1 < pEnd1 )
+ {
+ int Entry0 = Abc_Lit2LitL( Vec_IntArray(vMap0), *pBeg0 );
+ int Entry1 = Abc_Lit2LitL( Vec_IntArray(vMap1), *pBeg1 );
+ assert( *pBeg0 && *pBeg1 );
+ if ( Entry0 == Entry1 )
+ {
+ Vec_IntPush( vShared0, *pBeg0++ );
+ Vec_IntPush( vShared1, *pBeg1++ );
+ }
+ else if ( Entry0 > Entry1 )
+ Vec_IntPush( vUnique0, *pBeg0++ );
+ else
+ Vec_IntPush( vUnique1, *pBeg1++ );
+ }
+ while ( pBeg0 < pEnd0 )
+ Vec_IntPush( vUnique0, *pBeg0++ );
+ while ( pBeg1 < pEnd1 )
+ Vec_IntPush( vUnique1, *pBeg1++ );
+ assert( Vec_IntSize(vShared0) == Vec_IntSize(vShared1) );
+ assert( Vec_IntSize(vShared0) + Vec_IntSize(vUnique0) == Vec_IntSize(vLevel0) );
+ assert( Vec_IntSize(vShared1) + Vec_IntSize(vUnique1) == Vec_IntSize(vLevel1) );
+ }
+ nTotal = Vec_WecSizeSize(pBox0->vShared);
+ printf( "Box0: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox0->vLeafLits) );
+ printf( "Box1: Matched %d entries out of %d.\n", nTotal, Vec_WecSizeSize(pBox1->vLeafLits) );
+
+ //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vShared, Vec_IntArray(vMap0), 0 );
+ //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vShared, Vec_IntArray(vMap1), 0 );
+ //printf( "\n" );
+
+ //Acec_MatchPrintEquivLits( pBox0->pGia, pBox0->vUnique, Vec_IntArray(vMap0), 0 );
+ //Acec_MatchPrintEquivLits( pBox1->pGia, pBox1->vUnique, Vec_IntArray(vMap1), 0 );
+
+ Vec_IntFree( vMap0 );
+ Vec_IntFree( vMap1 );
+ return nTotal;
+}
+
+/**Function*************************************************************
+
Synopsis []
Description []
@@ -42,15 +485,63 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
-int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars )
-{
- Vec_Int_t * vOrder0 = Gia_PolynReorder( pGia0, pPars->fVerbose, pPars->fVeryVerbose );
- Vec_Int_t * vOrder1 = Gia_PolynReorder( pGia1, pPars->fVerbose, pPars->fVeryVerbose );
- Gia_PolynBuild( pGia0, vOrder0, 0, pPars->fVerbose, pPars->fVeryVerbose );
- Gia_PolynBuild( pGia1, vOrder1, 0, pPars->fVerbose, pPars->fVeryVerbose );
- Vec_IntFree( vOrder0 );
- Vec_IntFree( vOrder1 );
- return 1;
+int Acec_Solve( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Acec_ParCec_t * pPars )
+{
+ int status = -1;
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pMiter;
+ Gia_Man_t * pGia0n = pGia0, * pGia1n = pGia1;
+ Cec_ParCec_t ParsCec, * pCecPars = &ParsCec;
+// Vec_Bit_t * vIgnore0 = pPars->fBooth ? Acec_BoothFindPPG(pGia0) : NULL;
+// Vec_Bit_t * vIgnore1 = pPars->fBooth ? Acec_BoothFindPPG(pGia1) : NULL;
+// Acec_Box_t * pBox0 = Acec_DeriveBox( pGia0, vIgnore0, 0, 0, pPars->fVerbose );
+// Acec_Box_t * pBox1 = Acec_DeriveBox( pGia1, vIgnore1, 0, 0, pPars->fVerbose );
+// Vec_BitFreeP( &vIgnore0 );
+// Vec_BitFreeP( &vIgnore1 );
+ Acec_Box_t * pBox0 = Acec_ProduceBox( pGia0, pPars->fVerbose );
+ Acec_Box_t * pBox1 = Acec_ProduceBox( pGia1, pPars->fVerbose );
+ if ( pBox0 == NULL || pBox1 == NULL ) // cannot match
+ printf( "Cannot find arithmetic boxes in both LHS and RHS. Trying regular CEC.\n" );
+ else if ( !Acec_MatchBoxes( pBox0, pBox1 ) ) // cannot find matching
+ printf( "Cannot match arithmetic boxes in LHS and RHS. Trying regular CEC.\n" );
+ else
+ {
+ pGia0n = Acec_InsertBox( pBox0, 0 );
+ pGia1n = Acec_InsertBox( pBox1, 0 );
+ printf( "Matching of adder trees in LHS and RHS succeeded. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ // remove the last output
+ Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-1, 0 );
+ Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-1, 0 );
+
+ Gia_ManPatchCoDriver( pGia0n, Gia_ManCoNum(pGia0n)-2, 0 );
+ Gia_ManPatchCoDriver( pGia1n, Gia_ManCoNum(pGia1n)-2, 0 );
+ }
+ // solve regular CEC problem
+ Cec_ManCecSetDefaultParams( pCecPars );
+ pCecPars->nBTLimit = pPars->nBTLimit;
+ pMiter = Gia_ManMiter( pGia0n, pGia1n, 0, 1, 0, 0, pPars->fVerbose );
+ if ( pMiter )
+ {
+ int fDumpMiter = 0;
+ if ( fDumpMiter )
+ {
+ Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "acec_miter.aig" );
+ Gia_AigerWrite( pMiter, "acec_miter.aig", 0, 0 );
+ }
+ status = Cec_ManVerify( pMiter, pCecPars );
+ ABC_SWAP( Abc_Cex_t *, pGia0->pCexComb, pMiter->pCexComb );
+ Gia_ManStop( pMiter );
+ }
+ else
+ printf( "Miter computation has failed.\n" );
+ if ( pGia0n != pGia0 )
+ Gia_ManStop( pGia0n );
+ if ( pGia1n != pGia1 )
+ Gia_ManStop( pGia1n );
+ Acec_BoxFreeP( &pBox0 );
+ Acec_BoxFreeP( &pBox1 );
+ return status;
}
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h
index e761e56e..c4c8061e 100644
--- a/src/proof/acec/acecInt.h
+++ b/src/proof/acec/acecInt.h
@@ -27,7 +27,6 @@
////////////////////////////////////////////////////////////////////////
#include "aig/gia/gia.h"
-#include "proof/cec/cec.h"
#include "acec.h"
////////////////////////////////////////////////////////////////////////
@@ -38,6 +37,17 @@
ABC_NAMESPACE_HEADER_START
+typedef struct Acec_Box_t_ Acec_Box_t;
+struct Acec_Box_t_
+{
+ Gia_Man_t * pGia; // AIG manager
+ Vec_Wec_t * vAdds; // adders by rank
+ Vec_Wec_t * vLeafLits; // leaf literals by rank
+ Vec_Wec_t * vRootLits; // root literals by rank
+ Vec_Wec_t * vShared; // shared leaves
+ Vec_Wec_t * vUnique; // unique leaves
+};
+
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
@@ -46,6 +56,12 @@ ABC_NAMESPACE_HEADER_START
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
+static inline int Acec_SignBit( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> b) & 1; }
+static inline int Acec_SignBit2( Vec_Int_t * vAdds, int iBox, int b ) { return (Vec_IntEntry(vAdds, 6*iBox+5) >> (16+b)) & 1; }
+
+static inline void Acec_SignSetBit( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << b); }
+static inline void Acec_SignSetBit2( Vec_Int_t * vAdds, int iBox, int b, int v ) { if ( v ) *Vec_IntEntryP(vAdds, 6*iBox+5) |= (1 << (16+b)); }
+
////////////////////////////////////////////////////////////////////////
/// ITERATORS ///
////////////////////////////////////////////////////////////////////////
@@ -54,9 +70,28 @@ ABC_NAMESPACE_HEADER_START
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
+/*=== acecCo.c ========================================================*/
+extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts );
+extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes );
+/*=== acecMult.c ========================================================*/
+extern Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits );
+extern Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p );
+extern Vec_Bit_t * Acec_MultMarkPPs( Gia_Man_t * p );
+/*=== acecNorm.c ========================================================*/
+extern void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] );
+extern Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll );
+/*=== acecTree.c ========================================================*/
+extern void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds );
+extern void Acec_TreePrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds );
+extern Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose );
+extern void Acec_BoxFreeP( Acec_Box_t ** ppBox );
/*=== acecUtil.c ========================================================*/
extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose );
extern Vec_Int_t * Gia_PolynCollectLastXor( Gia_Man_t * pGia, int fVerbose );
+/*=== acecUtil.c ========================================================*/
+extern Acec_Box_t * Acec_ProduceBox( Gia_Man_t * p, int fVerbose );
+
+
ABC_NAMESPACE_HEADER_END
diff --git a/src/proof/acec/acecMult.c b/src/proof/acec/acecMult.c
new file mode 100644
index 00000000..c63fdde2
--- /dev/null
+++ b/src/proof/acec/acecMult.c
@@ -0,0 +1,617 @@
+/**CFile****************************************************************
+
+ FileName [acecMult.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Multiplier.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecMult.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "acecInt.h"
+#include "misc/extra/extra.h"
+#include "misc/util/utilTruth.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+unsigned s_Classes4a[96] = {
+ 0xD728, 0xB748, 0x9F60, 0xD278, 0xB478, 0x96F0, 0xC66C, 0x96CC, 0x9C6C, 0x96AA, 0xA66A, 0x9A6A,
+ 0x28D7, 0x48B7, 0x609F, 0x2D87, 0x4B87, 0x690F, 0x3993, 0x6933, 0x6393, 0x6955, 0x5995, 0x6595,
+ 0xEB14, 0xED12, 0xF906, 0xE1B4, 0xE1D2, 0xF096, 0xC99C, 0xCC96, 0xC9C6, 0xAA96, 0xA99A, 0xA9A6,
+ 0x14EB, 0x12ED, 0x06F9, 0x1E4B, 0x1E2D, 0x0F69, 0x3663, 0x3369, 0x3639, 0x5569, 0x5665, 0x5659,
+ 0x7D82, 0x7B84, 0x6F90, 0x78D2, 0x78B4, 0x69F0, 0x6CC6, 0x69CC, 0x6C9C, 0x69AA, 0x6AA6, 0x6A9A,
+ 0x827D, 0x847B, 0x906F, 0x872D, 0x874B, 0x960F, 0x9339, 0x9633, 0x9363, 0x9655, 0x9559, 0x9565,
+ 0xBE41, 0xDE21, 0xF609, 0xB4E1, 0xD2E1, 0xF069, 0x9CC9, 0xCC69, 0xC6C9, 0xAA69, 0x9AA9, 0xA6A9,
+ 0x41BE, 0x21DE, 0x09F6, 0x4B1E, 0x2D1E, 0x0F96, 0x6336, 0x3396, 0x3936, 0x5596, 0x6556, 0x5956
+};
+
+unsigned s_Classes4b[384] = {
+ 0x35C0, 0x53A0, 0x1DC0, 0x4788, 0x2788, 0x1BA0, 0x3C50, 0x5A30, 0x1CD0, 0x4878, 0x2878, 0x1AB0,
+ 0x34C4, 0x606C, 0x3C44, 0x660C, 0x268C, 0x286C, 0x606A, 0x52A2, 0x486A, 0x468A, 0x660A, 0x5A22,
+ 0x3AC0, 0x5CA0, 0x2EC0, 0x7488, 0x7288, 0x4EA0, 0x3CA0, 0x5AC0, 0x2CE0, 0x7848, 0x7828, 0x4AE0,
+ 0x38C8, 0x6C60, 0x3C88, 0x66C0, 0x62C8, 0x6C28, 0x6A60, 0x58A8, 0x6A48, 0x64A8, 0x66A0, 0x5A88,
+ 0xC530, 0xA350, 0xD10C, 0x8B44, 0x8D22, 0xB10A, 0xC350, 0xA530, 0xD01C, 0x84B4, 0x82D2, 0xB01A,
+ 0xC434, 0x909C, 0xC344, 0x990C, 0x8C26, 0x82C6, 0x909A, 0xA252, 0x84A6, 0x8A46, 0x990A, 0xA522,
+ 0xCA30, 0xAC50, 0xE20C, 0xB844, 0xD822, 0xE40A, 0xC3A0, 0xA5C0, 0xE02C, 0xB484, 0xD282, 0xE04A,
+ 0xC838, 0x9C90, 0xC388, 0x99C0, 0xC862, 0xC682, 0x9A90, 0xA858, 0xA684, 0xA864, 0x99A0, 0xA588,
+ 0x530C, 0x350A, 0x4730, 0x1D22, 0x1B44, 0x2750, 0x503C, 0x305A, 0x4370, 0x12D2, 0x14B4, 0x2570,
+ 0x434C, 0x06C6, 0x443C, 0x0C66, 0x194C, 0x149C, 0x06A6, 0x252A, 0x129A, 0x192A, 0x0A66, 0x225A,
+ 0xA30C, 0xC50A, 0x8B30, 0xD122, 0xB144, 0x8D50, 0xA03C, 0xC05A, 0x83B0, 0xD212, 0xB414, 0x85D0,
+ 0x838C, 0xC606, 0x883C, 0xC066, 0x91C4, 0x9C14, 0xA606, 0x858A, 0x9A12, 0x91A2, 0xA066, 0x885A,
+ 0x5C03, 0x3A05, 0x7403, 0x2E11, 0x4E11, 0x7205, 0x50C3, 0x30A5, 0x7043, 0x21E1, 0x41E1, 0x7025,
+ 0x4C43, 0x09C9, 0x44C3, 0x0C99, 0x4C19, 0x41C9, 0x09A9, 0x2A25, 0x21A9, 0x2A19, 0x0A99, 0x22A5,
+ 0xAC03, 0xCA05, 0xB803, 0xE211, 0xE411, 0xD805, 0xA0C3, 0xC0A5, 0xB083, 0xE121, 0xE141, 0xD085,
+ 0x8C83, 0xC909, 0x88C3, 0xC099, 0xC491, 0xC941, 0xA909, 0x8A85, 0xA921, 0xA291, 0xA099, 0x88A5,
+ 0xC035, 0xA053, 0xC01D, 0x8847, 0x8827, 0xA01B, 0xC305, 0xA503, 0xC10D, 0x8487, 0x8287, 0xA10B,
+ 0xC131, 0x9093, 0xC311, 0x9903, 0x8923, 0x8293, 0x9095, 0xA151, 0x8495, 0x8945, 0x9905, 0xA511,
+ 0xC03A, 0xA05C, 0xC02E, 0x8874, 0x8872, 0xA04E, 0xC30A, 0xA50C, 0xC20E, 0x8784, 0x8782, 0xA40E,
+ 0xC232, 0x9390, 0xC322, 0x9930, 0x9832, 0x9382, 0x9590, 0xA454, 0x9584, 0x9854, 0x9950, 0xA544,
+ 0x30C5, 0x50A3, 0x0CD1, 0x448B, 0x228D, 0x0AB1, 0x3C05, 0x5A03, 0x0DC1, 0x484B, 0x282D, 0x0BA1,
+ 0x31C1, 0x6063, 0x3C11, 0x6603, 0x2389, 0x2839, 0x6065, 0x51A1, 0x4859, 0x4589, 0x6605, 0x5A11,
+ 0x30CA, 0x50AC, 0x0CE2, 0x44B8, 0x22D8, 0x0AE4, 0x3C0A, 0x5A0C, 0x0EC2, 0x4B48, 0x2D28, 0x0EA4,
+ 0x32C2, 0x6360, 0x3C22, 0x6630, 0x3298, 0x3928, 0x6560, 0x54A4, 0x5948, 0x5498, 0x6650, 0x5A44,
+ 0x0C53, 0x0A35, 0x3047, 0x221D, 0x441B, 0x5027, 0x05C3, 0x03A5, 0x3407, 0x212D, 0x414B, 0x5207,
+ 0x1C13, 0x0939, 0x11C3, 0x0399, 0x4613, 0x4163, 0x0959, 0x1A15, 0x2165, 0x2615, 0x0599, 0x11A5,
+ 0x0CA3, 0x0AC5, 0x308B, 0x22D1, 0x44B1, 0x508D, 0x0AC3, 0x0CA5, 0x380B, 0x2D21, 0x4B41, 0x580D,
+ 0x2C23, 0x3909, 0x22C3, 0x3099, 0x6431, 0x6341, 0x5909, 0x4A45, 0x6521, 0x6251, 0x5099, 0x44A5,
+ 0x035C, 0x053A, 0x0374, 0x112E, 0x114E, 0x0572, 0x053C, 0x035A, 0x0734, 0x121E, 0x141E, 0x0752,
+ 0x131C, 0x0636, 0x113C, 0x0366, 0x1346, 0x1436, 0x0656, 0x151A, 0x1256, 0x1526, 0x0566, 0x115A,
+ 0x03AC, 0x05CA, 0x03B8, 0x11E2, 0x11E4, 0x05D8, 0x0A3C, 0x0C5A, 0x0B38, 0x1E12, 0x1E14, 0x0D58,
+ 0x232C, 0x3606, 0x223C, 0x3066, 0x3164, 0x3614, 0x5606, 0x454A, 0x5612, 0x5162, 0x5066, 0x445A
+};
+
+unsigned s_Classes4c[768] = {
+ 0x35C0, 0x53A0, 0x1DC0, 0x4788, 0x2788, 0x1BA0, 0x3C50, 0x5A30, 0x1CD0, 0x4878, 0x2878, 0x1AB0,
+ 0x34C4, 0x606C, 0x3C44, 0x660C, 0x268C, 0x286C, 0x606A, 0x52A2, 0x486A, 0x468A, 0x660A, 0x5A22,
+ 0xCA3F, 0xAC5F, 0xE23F, 0xB877, 0xD877, 0xE45F, 0xC3AF, 0xA5CF, 0xE32F, 0xB787, 0xD787, 0xE54F,
+ 0xCB3B, 0x9F93, 0xC3BB, 0x99F3, 0xD973, 0xD793, 0x9F95, 0xAD5D, 0xB795, 0xB975, 0x99F5, 0xA5DD,
+ 0x3AC0, 0x5CA0, 0x2EC0, 0x7488, 0x7288, 0x4EA0, 0x3CA0, 0x5AC0, 0x2CE0, 0x7848, 0x7828, 0x4AE0,
+ 0x38C8, 0x6C60, 0x3C88, 0x66C0, 0x62C8, 0x6C28, 0x6A60, 0x58A8, 0x6A48, 0x64A8, 0x66A0, 0x5A88,
+ 0xC53F, 0xA35F, 0xD13F, 0x8B77, 0x8D77, 0xB15F, 0xC35F, 0xA53F, 0xD31F, 0x87B7, 0x87D7, 0xB51F,
+ 0xC737, 0x939F, 0xC377, 0x993F, 0x9D37, 0x93D7, 0x959F, 0xA757, 0x95B7, 0x9B57, 0x995F, 0xA577,
+ 0xC530, 0xA350, 0xD10C, 0x8B44, 0x8D22, 0xB10A, 0xC350, 0xA530, 0xD01C, 0x84B4, 0x82D2, 0xB01A,
+ 0xC434, 0x909C, 0xC344, 0x990C, 0x8C26, 0x82C6, 0x909A, 0xA252, 0x84A6, 0x8A46, 0x990A, 0xA522,
+ 0x3ACF, 0x5CAF, 0x2EF3, 0x74BB, 0x72DD, 0x4EF5, 0x3CAF, 0x5ACF, 0x2FE3, 0x7B4B, 0x7D2D, 0x4FE5,
+ 0x3BCB, 0x6F63, 0x3CBB, 0x66F3, 0x73D9, 0x7D39, 0x6F65, 0x5DAD, 0x7B59, 0x75B9, 0x66F5, 0x5ADD,
+ 0xCA30, 0xAC50, 0xE20C, 0xB844, 0xD822, 0xE40A, 0xC3A0, 0xA5C0, 0xE02C, 0xB484, 0xD282, 0xE04A,
+ 0xC838, 0x9C90, 0xC388, 0x99C0, 0xC862, 0xC682, 0x9A90, 0xA858, 0xA684, 0xA864, 0x99A0, 0xA588,
+ 0x35CF, 0x53AF, 0x1DF3, 0x47BB, 0x27DD, 0x1BF5, 0x3C5F, 0x5A3F, 0x1FD3, 0x4B7B, 0x2D7D, 0x1FB5,
+ 0x37C7, 0x636F, 0x3C77, 0x663F, 0x379D, 0x397D, 0x656F, 0x57A7, 0x597B, 0x579B, 0x665F, 0x5A77,
+ 0x530C, 0x350A, 0x4730, 0x1D22, 0x1B44, 0x2750, 0x503C, 0x305A, 0x4370, 0x12D2, 0x14B4, 0x2570,
+ 0x434C, 0x06C6, 0x443C, 0x0C66, 0x194C, 0x149C, 0x06A6, 0x252A, 0x129A, 0x192A, 0x0A66, 0x225A,
+ 0xACF3, 0xCAF5, 0xB8CF, 0xE2DD, 0xE4BB, 0xD8AF, 0xAFC3, 0xCFA5, 0xBC8F, 0xED2D, 0xEB4B, 0xDA8F,
+ 0xBCB3, 0xF939, 0xBBC3, 0xF399, 0xE6B3, 0xEB63, 0xF959, 0xDAD5, 0xED65, 0xE6D5, 0xF599, 0xDDA5,
+ 0xA30C, 0xC50A, 0x8B30, 0xD122, 0xB144, 0x8D50, 0xA03C, 0xC05A, 0x83B0, 0xD212, 0xB414, 0x85D0,
+ 0x838C, 0xC606, 0x883C, 0xC066, 0x91C4, 0x9C14, 0xA606, 0x858A, 0x9A12, 0x91A2, 0xA066, 0x885A,
+ 0x5CF3, 0x3AF5, 0x74CF, 0x2EDD, 0x4EBB, 0x72AF, 0x5FC3, 0x3FA5, 0x7C4F, 0x2DED, 0x4BEB, 0x7A2F,
+ 0x7C73, 0x39F9, 0x77C3, 0x3F99, 0x6E3B, 0x63EB, 0x59F9, 0x7A75, 0x65ED, 0x6E5D, 0x5F99, 0x77A5,
+ 0x5C03, 0x3A05, 0x7403, 0x2E11, 0x4E11, 0x7205, 0x50C3, 0x30A5, 0x7043, 0x21E1, 0x41E1, 0x7025,
+ 0x4C43, 0x09C9, 0x44C3, 0x0C99, 0x4C19, 0x41C9, 0x09A9, 0x2A25, 0x21A9, 0x2A19, 0x0A99, 0x22A5,
+ 0xA3FC, 0xC5FA, 0x8BFC, 0xD1EE, 0xB1EE, 0x8DFA, 0xAF3C, 0xCF5A, 0x8FBC, 0xDE1E, 0xBE1E, 0x8FDA,
+ 0xB3BC, 0xF636, 0xBB3C, 0xF366, 0xB3E6, 0xBE36, 0xF656, 0xD5DA, 0xDE56, 0xD5E6, 0xF566, 0xDD5A,
+ 0xAC03, 0xCA05, 0xB803, 0xE211, 0xE411, 0xD805, 0xA0C3, 0xC0A5, 0xB083, 0xE121, 0xE141, 0xD085,
+ 0x8C83, 0xC909, 0x88C3, 0xC099, 0xC491, 0xC941, 0xA909, 0x8A85, 0xA921, 0xA291, 0xA099, 0x88A5,
+ 0x53FC, 0x35FA, 0x47FC, 0x1DEE, 0x1BEE, 0x27FA, 0x5F3C, 0x3F5A, 0x4F7C, 0x1EDE, 0x1EBE, 0x2F7A,
+ 0x737C, 0x36F6, 0x773C, 0x3F66, 0x3B6E, 0x36BE, 0x56F6, 0x757A, 0x56DE, 0x5D6E, 0x5F66, 0x775A,
+ 0xC035, 0xA053, 0xC01D, 0x8847, 0x8827, 0xA01B, 0xC305, 0xA503, 0xC10D, 0x8487, 0x8287, 0xA10B,
+ 0xC131, 0x9093, 0xC311, 0x9903, 0x8923, 0x8293, 0x9095, 0xA151, 0x8495, 0x8945, 0x9905, 0xA511,
+ 0x3FCA, 0x5FAC, 0x3FE2, 0x77B8, 0x77D8, 0x5FE4, 0x3CFA, 0x5AFC, 0x3EF2, 0x7B78, 0x7D78, 0x5EF4,
+ 0x3ECE, 0x6F6C, 0x3CEE, 0x66FC, 0x76DC, 0x7D6C, 0x6F6A, 0x5EAE, 0x7B6A, 0x76BA, 0x66FA, 0x5AEE,
+ 0xC03A, 0xA05C, 0xC02E, 0x8874, 0x8872, 0xA04E, 0xC30A, 0xA50C, 0xC20E, 0x8784, 0x8782, 0xA40E,
+ 0xC232, 0x9390, 0xC322, 0x9930, 0x9832, 0x9382, 0x9590, 0xA454, 0x9584, 0x9854, 0x9950, 0xA544,
+ 0x3FC5, 0x5FA3, 0x3FD1, 0x778B, 0x778D, 0x5FB1, 0x3CF5, 0x5AF3, 0x3DF1, 0x787B, 0x787D, 0x5BF1,
+ 0x3DCD, 0x6C6F, 0x3CDD, 0x66CF, 0x67CD, 0x6C7D, 0x6A6F, 0x5BAB, 0x6A7B, 0x67AB, 0x66AF, 0x5ABB,
+ 0x30C5, 0x50A3, 0x0CD1, 0x448B, 0x228D, 0x0AB1, 0x3C05, 0x5A03, 0x0DC1, 0x484B, 0x282D, 0x0BA1,
+ 0x31C1, 0x6063, 0x3C11, 0x6603, 0x2389, 0x2839, 0x6065, 0x51A1, 0x4859, 0x4589, 0x6605, 0x5A11,
+ 0xCF3A, 0xAF5C, 0xF32E, 0xBB74, 0xDD72, 0xF54E, 0xC3FA, 0xA5FC, 0xF23E, 0xB7B4, 0xD7D2, 0xF45E,
+ 0xCE3E, 0x9F9C, 0xC3EE, 0x99FC, 0xDC76, 0xD7C6, 0x9F9A, 0xAE5E, 0xB7A6, 0xBA76, 0x99FA, 0xA5EE,
+ 0x30CA, 0x50AC, 0x0CE2, 0x44B8, 0x22D8, 0x0AE4, 0x3C0A, 0x5A0C, 0x0EC2, 0x4B48, 0x2D28, 0x0EA4,
+ 0x32C2, 0x6360, 0x3C22, 0x6630, 0x3298, 0x3928, 0x6560, 0x54A4, 0x5948, 0x5498, 0x6650, 0x5A44,
+ 0xCF35, 0xAF53, 0xF31D, 0xBB47, 0xDD27, 0xF51B, 0xC3F5, 0xA5F3, 0xF13D, 0xB4B7, 0xD2D7, 0xF15B,
+ 0xCD3D, 0x9C9F, 0xC3DD, 0x99CF, 0xCD67, 0xC6D7, 0x9A9F, 0xAB5B, 0xA6B7, 0xAB67, 0x99AF, 0xA5BB,
+ 0x0C53, 0x0A35, 0x3047, 0x221D, 0x441B, 0x5027, 0x05C3, 0x03A5, 0x3407, 0x212D, 0x414B, 0x5207,
+ 0x1C13, 0x0939, 0x11C3, 0x0399, 0x4613, 0x4163, 0x0959, 0x1A15, 0x2165, 0x2615, 0x0599, 0x11A5,
+ 0xF3AC, 0xF5CA, 0xCFB8, 0xDDE2, 0xBBE4, 0xAFD8, 0xFA3C, 0xFC5A, 0xCBF8, 0xDED2, 0xBEB4, 0xADF8,
+ 0xE3EC, 0xF6C6, 0xEE3C, 0xFC66, 0xB9EC, 0xBE9C, 0xF6A6, 0xE5EA, 0xDE9A, 0xD9EA, 0xFA66, 0xEE5A,
+ 0x0CA3, 0x0AC5, 0x308B, 0x22D1, 0x44B1, 0x508D, 0x0AC3, 0x0CA5, 0x380B, 0x2D21, 0x4B41, 0x580D,
+ 0x2C23, 0x3909, 0x22C3, 0x3099, 0x6431, 0x6341, 0x5909, 0x4A45, 0x6521, 0x6251, 0x5099, 0x44A5,
+ 0xF35C, 0xF53A, 0xCF74, 0xDD2E, 0xBB4E, 0xAF72, 0xF53C, 0xF35A, 0xC7F4, 0xD2DE, 0xB4BE, 0xA7F2,
+ 0xD3DC, 0xC6F6, 0xDD3C, 0xCF66, 0x9BCE, 0x9CBE, 0xA6F6, 0xB5BA, 0x9ADE, 0x9DAE, 0xAF66, 0xBB5A,
+ 0x035C, 0x053A, 0x0374, 0x112E, 0x114E, 0x0572, 0x053C, 0x035A, 0x0734, 0x121E, 0x141E, 0x0752,
+ 0x131C, 0x0636, 0x113C, 0x0366, 0x1346, 0x1436, 0x0656, 0x151A, 0x1256, 0x1526, 0x0566, 0x115A,
+ 0xFCA3, 0xFAC5, 0xFC8B, 0xEED1, 0xEEB1, 0xFA8D, 0xFAC3, 0xFCA5, 0xF8CB, 0xEDE1, 0xEBE1, 0xF8AD,
+ 0xECE3, 0xF9C9, 0xEEC3, 0xFC99, 0xECB9, 0xEBC9, 0xF9A9, 0xEAE5, 0xEDA9, 0xEAD9, 0xFA99, 0xEEA5,
+ 0x03AC, 0x05CA, 0x03B8, 0x11E2, 0x11E4, 0x05D8, 0x0A3C, 0x0C5A, 0x0B38, 0x1E12, 0x1E14, 0x0D58,
+ 0x232C, 0x3606, 0x223C, 0x3066, 0x3164, 0x3614, 0x5606, 0x454A, 0x5612, 0x5162, 0x5066, 0x445A,
+ 0xFC53, 0xFA35, 0xFC47, 0xEE1D, 0xEE1B, 0xFA27, 0xF5C3, 0xF3A5, 0xF4C7, 0xE1ED, 0xE1EB, 0xF2A7,
+ 0xDCD3, 0xC9F9, 0xDDC3, 0xCF99, 0xCE9B, 0xC9EB, 0xA9F9, 0xBAB5, 0xA9ED, 0xAE9D, 0xAF99, 0xBBA5
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes NPN-canonical form using brute-force methods.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Extra_TruthCanonNPN2( unsigned uTruth, int nVars, Vec_Int_t * vRes )
+{
+ static int nVarsOld, nPerms;
+ static char ** pPerms = NULL;
+
+ unsigned uTruthMin, uTruthC, uPhase, uPerm;
+ int nMints, k, i;
+
+ if ( pPerms == NULL )
+ {
+ nPerms = Extra_Factorial( nVars );
+ pPerms = Extra_Permutations( nVars );
+ nVarsOld = nVars;
+ }
+ else if ( nVarsOld != nVars )
+ {
+ ABC_FREE( pPerms );
+ nPerms = Extra_Factorial( nVars );
+ pPerms = Extra_Permutations( nVars );
+ nVarsOld = nVars;
+ }
+
+ nMints = (1 << nVars);
+ uTruthC = (unsigned)( (~uTruth) & ((~((unsigned)0)) >> (32-nMints)) );
+ uTruthMin = 0xFFFFFFFF;
+ for ( i = 0; i < nMints; i++ )
+ {
+ uPhase = Extra_TruthPolarize( uTruth, i, nVars );
+ for ( k = 0; k < nPerms; k++ )
+ {
+ uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 );
+ Vec_IntPushUnique( vRes, uPerm );
+ if ( uTruthMin > uPerm )
+ uTruthMin = uPerm;
+ }
+ uPhase = Extra_TruthPolarize( uTruthC, i, nVars );
+ for ( k = 0; k < nPerms; k++ )
+ {
+ uPerm = Extra_TruthPermute( uPhase, pPerms[k], nVars, 0 );
+ Vec_IntPushUnique( vRes, uPerm );
+ if ( uTruthMin > uPerm )
+ uTruthMin = uPerm;
+ }
+ }
+ return uTruthMin;
+}
+
+void Acec_MultFuncTest5()
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
+ int i, Entry;
+
+ unsigned Truth = 0xF335ACC0;
+ unsigned Canon = Extra_TruthCanonNPN2( Truth, 5, vRes );
+
+ Extra_PrintHex( stdout, (unsigned*)&Truth, 5 ); printf( "\n" );
+ Extra_PrintHex( stdout, (unsigned*)&Canon, 5 ); printf( "\n" );
+
+ printf( "Members = %d.\n", Vec_IntSize(vRes) );
+ Vec_IntForEachEntry( vRes, Entry, i )
+ {
+ Extra_PrintHex( stdout, (unsigned*)&Entry, 5 );
+ printf( ", " );
+ if ( i % 8 == 7 )
+ printf( "\n" );
+ }
+
+ Vec_IntFree( vRes );
+}
+
+void Acec_MultFuncTest4()
+{
+ Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
+ int i, Entry;
+
+ unsigned Truth = 0x35C0;
+ //unsigned Truth = 0xD728;
+ unsigned Canon = Extra_TruthCanonNPN2( Truth, 4, vRes );
+
+ Extra_PrintHex( stdout, (unsigned*)&Truth, 4 ); printf( "\n" );
+ Extra_PrintHex( stdout, (unsigned*)&Canon, 4 ); printf( "\n" );
+
+ printf( "Members = %d.\n", Vec_IntSize(vRes) );
+ Vec_IntForEachEntry( vRes, Entry, i )
+ {
+ Extra_PrintHex( stdout, (unsigned*)&Entry, 4 );
+ printf( ", " );
+ if ( i % 12 == 11 )
+ printf( "\n" );
+ }
+
+ Vec_IntFree( vRes );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_MultCollectInputs( Vec_Int_t * vPairs, Vec_Int_t * vRanks, int iObj )
+{
+ Vec_Int_t * vItems = Vec_IntAlloc( 100 );
+ int k, iObj1, iObj2;
+ // collect all those appearing with this one
+ Vec_IntForEachEntryDouble( vPairs, iObj1, iObj2, k )
+ if ( iObj == iObj1 )
+ Vec_IntPushUnique( vItems, iObj2 );
+ else if ( iObj == iObj2 )
+ Vec_IntPushUnique( vItems, iObj1 );
+ // sort items by rank cost
+ Vec_IntSelectSortCost( Vec_IntArray(vItems), Vec_IntSize(vItems), vRanks );
+ return vItems;
+}
+Vec_Int_t * Acec_MultDetectInputs1( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits )
+{
+ Vec_Int_t * vInputs = Vec_IntAlloc( 100 );
+ Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vRanks = Vec_IntStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vPairs = Vec_IntAlloc( 100 );
+ Vec_Int_t * vItems = Vec_IntAlloc( 100 );
+ Vec_Int_t * vItems0;
+ Vec_Int_t * vItems1;
+ Vec_Int_t * vLevel;
+ int i, k, iLit, iObj, Count;
+ // count how many times each input appears
+ Vec_WecForEachLevel( vLeafLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ {
+ iObj = Abc_Lit2Var(iLit);
+ Vec_IntAddToEntry( vCounts, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), 1 );
+ Vec_IntAddToEntry( vCounts, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj), 1 );
+/*
+ printf( "Rank %2d : Leaf = %4d : (%2d, %2d)\n", i, iObj,
+ Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj) );
+ if ( k == Vec_IntSize(vLevel) - 1 )
+ printf( "\n" );
+*/
+ }
+ // count ranks for each one
+ Vec_WecForEachLevel( vLeafLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ {
+ iObj = Abc_Lit2Var(iLit);
+ if ( Vec_IntEntry(vCounts, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj)) < 2 )
+ {
+ printf( "Skipping %d.\n", iObj );
+ continue;
+ }
+ if ( Vec_IntEntry(vCounts, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj)) < 2 )
+ {
+ printf( "Skipping %d.\n", iObj );
+ continue;
+ }
+ Vec_IntAddToEntry( vRanks, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), i );
+ Vec_IntAddToEntry( vRanks, Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj), i );
+
+ Vec_IntPushTwo( vPairs, Gia_ObjFaninId0(Gia_ManObj(p, iObj), iObj), Gia_ObjFaninId1(Gia_ManObj(p, iObj), iObj) );
+ }
+
+ // print statistics
+ Vec_IntForEachEntry( vCounts, Count, i )
+ {
+ if ( !Count )
+ continue;
+ if ( !Vec_IntEntry(vRanks, i) )
+ continue;
+ Vec_IntPush( vItems, i );
+ printf( "Obj = %3d Occurs = %3d Ranks = %3d\n", i, Count, Vec_IntEntry(vRanks, i) );
+ }
+ // sort items by rank cost
+ Vec_IntSelectSortCost( Vec_IntArray(vItems), Vec_IntSize(vItems), vRanks );
+ // collect all those appearing with the last one
+ vItems0 = Acec_MultCollectInputs( vPairs, vRanks, Vec_IntEntryLast(vItems) );
+ Vec_IntAppend( vInputs, vItems0 );
+ // collect all those appearing with the last one
+ vItems1 = Acec_MultCollectInputs( vPairs, vRanks, Vec_IntEntryLast(vItems0) );
+ Vec_IntAppend( vInputs, vItems1 );
+
+ Vec_IntPrint( vItems0 );
+ Vec_IntPrint( vItems1 );
+
+ Vec_IntFree( vCounts );
+ Vec_IntFree( vRanks );
+ Vec_IntFree( vPairs );
+ Vec_IntFree( vItems );
+ Vec_IntFree( vItems0 );
+ Vec_IntFree( vItems1 );
+ return vInputs;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_MultDetectInputs( Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits )
+{
+ Vec_Int_t * vInputs = Vec_IntAlloc( 100 );
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vRanks = Vec_IntStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel;
+ int i, k, iLit, iObj, j, Entry;
+
+ ABC_FREE( p->pRefs );
+ Gia_ManCreateRefs( p );
+ Gia_ManForEachCiId( p, iObj, i )
+ printf( "%d=%d ", iObj, Gia_ObjRefNumId(p, iObj) );
+ printf( "\n" );
+ Gia_ManForEachAndId( p, iObj )
+ if ( Gia_ObjRefNumId(p, iObj) >= 4 )
+ printf( "%d=%d ", iObj, Gia_ObjRefNumId(p, iObj) );
+ printf( "\n" );
+
+ Vec_WecForEachLevel( vLeafLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ {
+ word Truth = Gia_ObjComputeTruth6Cis( p, iLit, vSupp, vTemp );
+ if ( Vec_IntSize(vSupp) >= 0 )
+ {
+ printf( "Leaf = %4d : ", Abc_Lit2Var(iLit) );
+ printf( "Rank = %2d ", i );
+ printf( "Supp = %2d ", Vec_IntSize(vSupp) );
+ Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
+ if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
+ if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
+ if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
+ printf( " " );
+ Vec_IntPrint( vSupp );
+ /*
+ if ( Truth == 0xF335ACC0F335ACC0 )
+ {
+ int iObj = Abc_Lit2Var(iLit);
+ Gia_Man_t * pGia0 = Gia_ManDupAndCones( p, &iObj, 1, 1 );
+ Gia_ManShow( pGia0, NULL, 0, 0, 0 );
+ Gia_ManStop( pGia0 );
+ }
+ */
+ }
+ // support rank counts
+ Vec_IntForEachEntry( vSupp, Entry, j )
+ {
+ Vec_IntAddToEntry( vRanks, Entry, i );
+ Vec_IntAddToEntry( vCounts, Entry, 1 );
+ }
+ if ( k == Vec_IntSize(vLevel)-1 )
+ printf( "\n" );
+ }
+
+ Vec_IntForEachEntry( vCounts, Entry, j )
+ if ( Entry )
+ printf( "%d=%d(%.2f) ", j, Entry, 1.0*Vec_IntEntry(vRanks, j)/Entry );
+ printf( "\n" );
+
+ Vec_IntFree( vSupp );
+ Vec_WrdFree( vTemp );
+ Vec_IntFree( vRanks );
+ Vec_IntFree( vCounts );
+ return vInputs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Mark nodes whose function is exactly that of a Booth PP.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Bit_t * Acec_MultMarkPPs( Gia_Man_t * p )
+{
+ word Saved[32] = {
+ ABC_CONST(0xF335ACC0F335ACC0),
+ ABC_CONST(0x35C035C035C035C0),
+ ABC_CONST(0xD728D728D728D728),
+ ABC_CONST(0xFD80FD80FD80FD80),
+ ABC_CONST(0xACC0ACC0ACC0ACC0),
+ ABC_CONST(0x7878787878787878),
+ ABC_CONST(0x2828282828282828),
+ ABC_CONST(0xD0D0D0D0D0D0D0D0),
+ ABC_CONST(0x8080808080808080),
+ ABC_CONST(0x8888888888888888),
+ ABC_CONST(0xAAAAAAAAAAAAAAAA),
+ ABC_CONST(0x5555555555555555),
+
+ ABC_CONST(0xD5A8D5A8D5A8D5A8),
+ ABC_CONST(0x2A572A572A572A57),
+ ABC_CONST(0xF3C0F3C0F3C0F3C0),
+ ABC_CONST(0x5858585858585858),
+ ABC_CONST(0xA7A7A7A7A7A7A7A7),
+ ABC_CONST(0x2727272727272727),
+ ABC_CONST(0xD8D8D8D8D8D8D8D8)
+ };
+
+ Vec_Bit_t * vRes = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ int i, iObj, nProds = 0;
+ Gia_ManCleanMark0(p);
+ Gia_ManForEachAndId( p, iObj )
+ {
+ word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp );
+ if ( Vec_IntSize(vSupp) > 6 )
+ continue;
+ vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize );
+ if ( Vec_IntSize(vSupp) > 5 )
+ continue;
+ for ( i = 0; i < 32 && Saved[i]; i++ )
+ {
+ if ( Truth == Saved[i] || Truth == ~Saved[i] )
+ {
+ Vec_BitWriteEntry( vRes, iObj, 1 );
+ nProds++;
+ break;
+ }
+ }
+ }
+ Gia_ManCleanMark0(p);
+ printf( "Collected %d pps.\n", nProds );
+ Vec_IntFree( vSupp );
+ Vec_WrdFree( vTemp );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_MultFindPPs_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vBold )
+{
+ Gia_Obj_t * pObj;
+ pObj = Gia_ManObj( p, iObj );
+ if ( pObj->fMark0 )
+ return;
+ pObj->fMark0 = 1;
+ if ( !Gia_ObjIsAnd(pObj) )
+ return;
+ Acec_MultFindPPs_rec( p, Gia_ObjFaninId0(pObj, iObj), vBold );
+ Acec_MultFindPPs_rec( p, Gia_ObjFaninId1(pObj, iObj), vBold );
+ Vec_IntPush( vBold, iObj );
+}
+Vec_Int_t * Acec_MultFindPPs( Gia_Man_t * p )
+{
+ word Saved[32] = {
+ ABC_CONST(0xF335ACC0F335ACC0),
+ ABC_CONST(0x35C035C035C035C0),
+ ABC_CONST(0xD728D728D728D728),
+ ABC_CONST(0xFD80FD80FD80FD80),
+ ABC_CONST(0xACC0ACC0ACC0ACC0),
+ ABC_CONST(0x7878787878787878),
+ ABC_CONST(0x2828282828282828),
+ ABC_CONST(0xD0D0D0D0D0D0D0D0),
+ ABC_CONST(0x8080808080808080),
+ ABC_CONST(0x8888888888888888),
+ ABC_CONST(0xAAAAAAAAAAAAAAAA),
+ ABC_CONST(0x5555555555555555),
+
+ ABC_CONST(0xD5A8D5A8D5A8D5A8),
+ ABC_CONST(0x2A572A572A572A57),
+ ABC_CONST(0xF3C0F3C0F3C0F3C0),
+ ABC_CONST(0x5858585858585858),
+ ABC_CONST(0xA7A7A7A7A7A7A7A7),
+ ABC_CONST(0x2727272727272727),
+ ABC_CONST(0xD8D8D8D8D8D8D8D8)
+ };
+
+ Vec_Int_t * vBold = Vec_IntAlloc( 100 );
+ Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
+ Vec_Wrd_t * vTemp = Vec_WrdStart( Gia_ManObjNum(p) );
+ int i, iObj, nProds = 0;
+ Gia_ManCleanMark0(p);
+ Gia_ManForEachAndId( p, iObj )
+ {
+ word Truth = Gia_ObjComputeTruth6Cis( p, Abc_Var2Lit(iObj, 0), vSupp, vTemp );
+ if ( Vec_IntSize(vSupp) > 6 )
+ continue;
+ vSupp->nSize = Abc_Tt6MinBase( &Truth, vSupp->pArray, vSupp->nSize );
+ if ( Vec_IntSize(vSupp) > 5 )
+ continue;
+ for ( i = 0; i < 32 && Saved[i]; i++ )
+ {
+ if ( Truth == Saved[i] || Truth == ~Saved[i] )
+ {
+ //printf( "*** Node %d is PP with support %d.\n", iObj, Vec_IntSize(vSupp) );
+ Acec_MultFindPPs_rec( p, iObj, vBold );
+ nProds++;
+ break;
+ }
+ }
+ /*
+ if ( Saved[i] )
+ {
+ printf( "Obj = %4d ", iObj );
+ Extra_PrintHex( stdout, (unsigned*)&Truth, Vec_IntSize(vSupp) );
+ if ( Vec_IntSize(vSupp) == 4 ) printf( " " );
+ if ( Vec_IntSize(vSupp) == 3 ) printf( " " );
+ if ( Vec_IntSize(vSupp) <= 2 ) printf( " " );
+ printf( " " );
+ Vec_IntPrint( vSupp );
+ }
+ */
+ }
+ Gia_ManCleanMark0(p);
+ printf( "Collected %d pps and %d nodes.\n", nProds, Vec_IntSize(vBold) );
+
+ Vec_IntFree( vSupp );
+ Vec_WrdFree( vTemp );
+ return vBold;
+}
+Vec_Bit_t * Acec_BoothFindPPG( Gia_Man_t * p )
+{
+ Vec_Bit_t * vIgnore = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vMap = Acec_MultFindPPs( p );
+ int i, Entry;
+ Vec_IntForEachEntry( vMap, Entry, i )
+ Vec_BitWriteEntry( vIgnore, Entry, 1 );
+ Vec_IntFree( vMap );
+ return vIgnore;
+}
+void Acec_MultFindPPsTest( Gia_Man_t * p )
+{
+ Vec_Int_t * vBold = Acec_MultFindPPs( p );
+ Gia_ManShow( p, vBold, 1, 0, 0 );
+ Vec_IntFree( vBold );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/acecNorm.c b/src/proof/acec/acecNorm.c
new file mode 100644
index 00000000..f2acb37b
--- /dev/null
+++ b/src/proof/acec/acecNorm.c
@@ -0,0 +1,226 @@
+/**CFile****************************************************************
+
+ FileName [acecNorm.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Adder tree normalization.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecNorm.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "acecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_InsertHadd( Gia_Man_t * pNew, int In[2], int Out[2] )
+{
+ int And, Or;
+ Out[1] = Gia_ManAppendAnd2( pNew, In[0], In[1] );
+ And = Gia_ManAppendAnd2( pNew, Abc_LitNot(In[0]), Abc_LitNot(In[1]) );
+ Or = Gia_ManAppendOr2( pNew, Out[1], And );
+ Out[0] = Abc_LitNot( Or );
+}
+void Acec_InsertFadd( Gia_Man_t * pNew, int In[3], int Out[2] )
+{
+ int In2[2], Out1[2], Out2[2];
+ Acec_InsertHadd( pNew, In, Out1 );
+ In2[0] = Out1[0];
+ In2[1] = In[2];
+ Acec_InsertHadd( pNew, In2, Out2 );
+ Out[0] = Out2[0];
+ Out[1] = Gia_ManAppendOr2( pNew, Out1[1], Out2[1] );
+}
+Vec_Int_t * Acec_InsertTree( Gia_Man_t * pNew, Vec_Wec_t * vLeafMap )
+{
+ Vec_Int_t * vRootRanks = Vec_IntAlloc( Vec_WecSize(vLeafMap) + 5 );
+ Vec_Int_t * vLevel;
+ int i, In[3], Out[2];
+ Vec_WecForEachLevel( vLeafMap, vLevel, i )
+ {
+ if ( Vec_IntSize(vLevel) == 0 )
+ {
+ Vec_IntPush( vRootRanks, 0 );
+ continue;
+ }
+ while ( Vec_IntSize(vLevel) > 1 )
+ {
+ if ( Vec_IntSize(vLevel) == 2 )
+ Vec_IntPush( vLevel, 0 );
+ //In[2] = Vec_IntPop( vLevel );
+ //In[1] = Vec_IntPop( vLevel );
+ //In[0] = Vec_IntPop( vLevel );
+
+ In[0] = Vec_IntEntry( vLevel, 0 );
+ Vec_IntDrop( vLevel, 0 );
+
+ In[1] = Vec_IntEntry( vLevel, 0 );
+ Vec_IntDrop( vLevel, 0 );
+
+ In[2] = Vec_IntEntry( vLevel, 0 );
+ Vec_IntDrop( vLevel, 0 );
+
+ Acec_InsertFadd( pNew, In, Out );
+ Vec_IntPush( vLevel, Out[0] );
+ if ( i+1 < Vec_WecSize(vLeafMap) )
+ vLevel = Vec_WecEntry(vLeafMap, i+1);
+ else
+ vLevel = Vec_WecPushLevel(vLeafMap);
+ Vec_IntPush( vLevel, Out[1] );
+ vLevel = Vec_WecEntry(vLeafMap, i);
+ }
+ assert( Vec_IntSize(vLevel) == 1 );
+ Vec_IntPush( vRootRanks, Vec_IntEntry(vLevel, 0) );
+ }
+ return vRootRanks;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_InsertBox_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return pObj->Value;
+ assert( Gia_ObjIsAnd(pObj) );
+ Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Acec_InsertBox_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ return (pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ));
+}
+Vec_Int_t * Acec_BuildTree( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t * vLeafLits, Vec_Int_t * vRootLits )
+{
+ Vec_Wec_t * vLeafMap = Vec_WecStart( Vec_WecSize(vLeafLits) );
+ Vec_Int_t * vLevel, * vRootRanks;
+ int i, k, iLit, iLitNew;
+ // add roo literals
+ if ( vRootLits )
+ Vec_IntForEachEntry( vRootLits, iLit, i )
+ {
+ if ( i < Vec_WecSize(vLeafMap) )
+ vLevel = Vec_WecEntry(vLeafMap, i);
+ else
+ vLevel = Vec_WecPushLevel(vLeafMap);
+ Vec_IntPush( vLevel, iLit );
+ }
+ // add other literals
+ Vec_WecForEachLevel( vLeafLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) );
+ iLitNew = Acec_InsertBox_rec( pNew, p, pObj );
+ iLitNew = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) );
+ Vec_WecPush( vLeafMap, i, iLitNew );
+ }
+ // construct map of root literals
+ vRootRanks = Acec_InsertTree( pNew, vLeafMap );
+ Vec_WecFree( vLeafMap );
+ return vRootRanks;
+}
+Gia_Man_t * Acec_InsertBox( Acec_Box_t * pBox, int fAll )
+{
+ Gia_Man_t * p = pBox->pGia;
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj;
+ Vec_Int_t * vRootRanks, * vLevel, * vTemp;
+ int i, k, iLit, iLitNew;
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManFillValue(p);
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ // implement tree
+ if ( fAll )
+ vRootRanks = Acec_BuildTree( pNew, p, pBox->vLeafLits, NULL );
+ else
+ {
+ assert( pBox->vShared != NULL );
+ assert( pBox->vUnique != NULL );
+ vRootRanks = Acec_BuildTree( pNew, p, pBox->vShared, NULL );
+ vRootRanks = Acec_BuildTree( pNew, p, pBox->vUnique, vTemp = vRootRanks );
+ Vec_IntFree( vTemp );
+ }
+ // update polarity of literals
+ Vec_WecForEachLevel( pBox->vRootLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ {
+ pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) );
+ iLitNew = k ? 0 : Vec_IntEntry( vRootRanks, i );
+ pObj->Value = Abc_LitNotCond( iLitNew, Abc_LitIsCompl(iLit) );
+ }
+ Vec_IntFree( vRootRanks );
+ // construct the outputs
+ Gia_ManForEachCo( p, pObj, i )
+ Acec_InsertBox_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Acec_Normalize( Gia_Man_t * pGia, int fBooth, int fVerbose )
+{
+ Vec_Bit_t * vIgnore = fBooth ? Acec_BoothFindPPG( pGia ) : NULL;
+ Acec_Box_t * pBox = Acec_DeriveBox( pGia, vIgnore, 0, 0, fVerbose );
+ Gia_Man_t * pNew = Acec_InsertBox( pBox, 1 );
+ Acec_BoxFreeP( &pBox );
+ Vec_BitFreeP( &vIgnore );
+ return pNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/acecPa.c b/src/proof/acec/acecPa.c
index ecaf2047..6b382d91 100644
--- a/src/proof/acec/acecPa.c
+++ b/src/proof/acec/acecPa.c
@@ -248,11 +248,6 @@ int Pas_ManComputeCuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vOrder, Ve
***********************************************************************/
void Pas_ManComputeCutsTest( Gia_Man_t * p )
{
- extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
- extern Vec_Int_t * Gia_PolynCoreOrder( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vAddCos, Vec_Int_t ** pvIns, Vec_Int_t ** pvOuts );
-
- extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
- extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
abctime clk = Abc_Clock();
Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
Vec_Int_t * vIns, * vOuts;
diff --git a/src/proof/acec/acecPool.c b/src/proof/acec/acecPool.c
index 08ee37f2..0868545e 100644
--- a/src/proof/acec/acecPool.c
+++ b/src/proof/acec/acecPool.c
@@ -303,17 +303,9 @@ void Acec_ManPrintRanks( Vec_Int_t * vPairs )
***********************************************************************/
void Acec_ManProfile( Gia_Man_t * p, int fVerbose )
{
- extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
- extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds );
- extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds );
- extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
- extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
-
abctime clk = Abc_Clock();
Vec_Wec_t * vBoxes; int i;
Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, fVerbose );
- Ree_ManRemoveTrivial( p, vAdds );
- Ree_ManRemoveContained( p, vAdds );
//Ree_ManPrintAdders( vAdds, 1 );
printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 );
@@ -396,13 +388,6 @@ Vec_Int_t * Acec_ManPoolTopMost( Gia_Man_t * p, Vec_Int_t * vAdds )
}
void Acec_ManPool( Gia_Man_t * p )
{
- extern Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose );
- extern Vec_Wec_t * Gia_PolynCoreOrderArray( Gia_Man_t * pGia, Vec_Int_t * vAdds, Vec_Int_t * vRootBoxes );
-
- extern int Ree_ManCountFadds( Vec_Int_t * vAdds );
- extern void Ree_ManPrintAdders( Vec_Int_t * vAdds, int fVerbose );
- extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds );
- extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds );
Vec_Int_t * vTops, * vTree;
Vec_Wec_t * vTrees;
@@ -413,8 +398,6 @@ void Acec_ManPool( Gia_Man_t * p )
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
clk = Abc_Clock();
- Ree_ManRemoveTrivial( p, vAdds );
- Ree_ManRemoveContained( p, vAdds );
nFadds = Ree_ManCountFadds( vAdds );
printf( "Detected %d FAs and %d HAs. ", nFadds, Vec_IntSize(vAdds)/6-nFadds );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
diff --git a/src/proof/acec/acecRe.c b/src/proof/acec/acecRe.c
index 26faad00..5e5ca688 100644
--- a/src/proof/acec/acecRe.c
+++ b/src/proof/acec/acecRe.c
@@ -147,6 +147,7 @@ static inline int Ree_ManCutFind( int iObj, int * pCut )
}
static inline int Ree_ManCutNotFind( int iObj1, int iObj2, int * pCut )
{
+ assert( pCut[0] == 3 );
if ( pCut[3] != iObj1 && pCut[3] != iObj2 ) return 0;
if ( pCut[2] != iObj1 && pCut[2] != iObj2 ) return 1;
if ( pCut[1] != iObj1 && pCut[1] != iObj2 ) return 2;
@@ -162,13 +163,19 @@ static inline int Ree_ManCutTruthOne( int * pCut0, int * pCut )
Truth0 = fComp0 ? ~Truth0 : Truth0;
if ( pCut0[0] == 2 )
{
- int Truths[3][8] = {
- { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, // {0,1,-}
- { 0x00, 0x05, 0x0A, 0x0F, 0x50, 0x55, 0x5A, 0x5F }, // {0,-,1}
- { 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F } // {-,0,1}
- };
- int Truth = Truths[Ree_ManCutNotFind(pCut0[1], pCut0[2], pCut)][Truth0 & 0x7];
- return 0xFF & (fComp0 ? ~Truth : Truth);
+ if ( pCut[0] == 3 )
+ {
+ int Truths[3][8] = {
+ { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, // {0,1,-}
+ { 0x00, 0x05, 0x0A, 0x0F, 0x50, 0x55, 0x5A, 0x5F }, // {0,-,1}
+ { 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F } // {-,0,1}
+ };
+ int Truth = Truths[Ree_ManCutNotFind(pCut0[1], pCut0[2], pCut)][Truth0 & 0x7];
+ return 0xFF & (fComp0 ? ~Truth : Truth);
+ }
+ assert( pCut[0] == 2 );
+ assert( pCut[1] == pCut0[1] && pCut[2] == pCut0[2] );
+ return pCut0[pCut0[0]+1];
}
if ( pCut0[0] == 1 )
{
@@ -236,10 +243,10 @@ int Ree_ObjComputeTruth( Gia_Man_t * p, int iObj, int * pCut )
SeeAlso []
***********************************************************************/
-void Ree_ManCutPrint( int * pCut, int Count, word Truth )
+void Ree_ManCutPrint( int * pCut, int Count, word Truth, int iObj )
{
int c;
- printf( "%d : ", Count );
+ printf( "%d : %d : ", Count, iObj );
for ( c = 1; c <= pCut[0]; c++ )
printf( "%3d ", pCut[c] );
for ( ; c <= 4; c++ )
@@ -290,7 +297,7 @@ void Ree_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_I
Vec_IntPushThree( vData, iObj, Value, TruthC );
}
if ( fVerbose )
- Ree_ManCutPrint( pCut, ++Count, TruthC );
+ Ree_ManCutPrint( pCut, ++Count, TruthC, iObj );
}
if ( !vXors )
return;
@@ -370,7 +377,7 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos
Vec_IntForEachEntryDouble( vXorOne, iObj, Truth, j )
Vec_IntForEachEntryDouble( vMajOne, iObj2, Truth2, k )
{
- int SignAnd[8] = {0x88, 0x44, 0x22, 0x11, 0xEE, 0xDD, 0xBB, 0x77};
+ int SignAnd[8] = {0x88, 0x44, 0x22, 0x11, 0x77, 0xBB, 0xDD, 0xEE};
int SignMaj[8] = {0xE8, 0xD4, 0xB2, 0x71, 0x8E, 0x4D, 0x2B, 0x17};
int n, SignXor = (Truth == 0x99 || Truth == 0x69) << 3;
for ( n = 0; n < 8; n++ )
@@ -390,8 +397,18 @@ Vec_Int_t * Ree_ManDeriveAdds( Hash_IntMan_t * p, Vec_Int_t * vData, int fVerbos
Vec_WecFree( vMajMap );
return vAdds;
}
+int Ree_ManCompare( int * pCut0, int * pCut1 )
+{
+ if ( pCut0[3] < pCut1[3] ) return -1;
+ if ( pCut0[3] > pCut1[3] ) return 1;
+ if ( pCut0[4] < pCut1[4] ) return -1;
+ if ( pCut0[4] > pCut1[4] ) return 1;
+ return 0;
+}
Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose )
{
+ extern void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds );
+ extern void Ree_ManRemoveContained( Gia_Man_t * p, Vec_Int_t * vAdds );
Gia_Obj_t * pObj;
int * pList0, * pList1, i, nCuts = 0;
Hash_IntMan_t * pHash = Hash_IntManStart( 1000 );
@@ -425,11 +442,15 @@ Vec_Int_t * Ree_ManComputeCuts( Gia_Man_t * p, Vec_Int_t ** pvXors, int fVerbose
Vec_IntFree( vTemp );
Vec_IntFree( vCuts );
vAdds = Ree_ManDeriveAdds( pHash, vData, fVerbose );
+ qsort( Vec_IntArray(vAdds), Vec_IntSize(vAdds)/6, 24, (int (*)(const void *, const void *))Ree_ManCompare );
if ( fVerbose )
printf( "Adders = %d. Total cuts = %d. Hashed cuts = %d. Hashed/Adders = %.2f.\n",
Vec_IntSize(vAdds)/6, Vec_IntSize(vData)/3, Hash_IntManEntryNum(pHash), 6.0*Hash_IntManEntryNum(pHash)/Vec_IntSize(vAdds) );
Vec_IntFree( vData );
Hash_IntManStop( pHash );
+ Ree_ManRemoveTrivial( p, vAdds );
+ Ree_ManRemoveContained( p, vAdds );
+ //Ree_ManPrintAdders( vAdds, 1 );
return vAdds;
}
@@ -503,6 +524,10 @@ void Ree_ManRemoveTrivial( Gia_Man_t * p, Vec_Int_t * vAdds )
{
pObjX = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+3) );
pObjM = Gia_ManObj( p, Vec_IntEntry(vAdds, 6*i+4) );
+ // rule out if MAJ is a fanout of XOR
+ //if ( pObjX == Gia_ObjFanin0(pObjM) || pObjX == Gia_ObjFanin1(pObjM) )
+ // continue;
+ // rule out if MAJ is a fanin of XOR and has no other fanouts
if ( (pObjM == Gia_ObjFanin0(pObjX) || pObjM == Gia_ObjFanin1(pObjX)) && Gia_ObjRefNum(p, pObjM) == 1 )
continue;
}
diff --git a/src/proof/acec/acecSt.c b/src/proof/acec/acecSt.c
index 63aa8131..d97dadc9 100644
--- a/src/proof/acec/acecSt.c
+++ b/src/proof/acec/acecSt.c
@@ -21,6 +21,8 @@
#include "acecInt.h"
#include "misc/vec/vecWec.h"
#include "misc/extra/extra.h"
+#include "aig/aig/aig.h"
+#include "opt/dar/dar.h"
ABC_NAMESPACE_IMPL_START
diff --git a/src/proof/acec/acecStruct.c b/src/proof/acec/acecStruct.c
new file mode 100644
index 00000000..6702e13b
--- /dev/null
+++ b/src/proof/acec/acecStruct.c
@@ -0,0 +1,271 @@
+/**CFile****************************************************************
+
+ FileName [acecStruct.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Core procedures.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecStruct.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "acecInt.h"
+#include "misc/vec/vecWec.h"
+#include "misc/extra/extra.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_StructDetectXorRoots( Gia_Man_t * p )
+{
+ Vec_Int_t * vXors = Vec_IntAlloc( 100 );
+ Vec_Bit_t * vXorIns = Vec_BitStart( Gia_ManObjNum(p) );
+ Gia_Obj_t * pFan0, * pFan1, * pObj;
+ int i, k = 0, Entry;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
+ continue;
+ Vec_IntPush( vXors, i );
+ Vec_BitWriteEntry( vXorIns, Gia_ObjId(p, Gia_Regular(pFan0)), 1 );
+ Vec_BitWriteEntry( vXorIns, Gia_ObjId(p, Gia_Regular(pFan1)), 1 );
+ }
+ // collect XORs that not inputs of other XORs
+ Vec_IntForEachEntry( vXors, Entry, i )
+ if ( !Vec_BitEntry(vXorIns, Entry) )
+ Vec_IntWriteEntry( vXors, k++, Entry );
+ Vec_IntShrink( vXors, k );
+ Vec_BitFree( vXorIns );
+ return vXors;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_StructAssignRanks( Gia_Man_t * p, Vec_Int_t * vXorRoots )
+{
+ Vec_Int_t * vDoubles = Vec_IntAlloc( 100 );
+ Gia_Obj_t * pFan0, * pFan1, * pObj;
+ int i, k, Fanins[2], Entry, Rank;
+ // map roots into their ranks
+ Vec_Int_t * vRanks = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Vec_IntForEachEntry( vXorRoots, Entry, i )
+ Vec_IntWriteEntry( vRanks, Entry, i );
+ // map nodes into their ranks
+ Gia_ManForEachAndReverse( p, pObj, i )
+ {
+ if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
+ continue;
+ Rank = Vec_IntEntry( vRanks, i );
+ // skip XORs that are not part of any tree
+ if ( Rank == -1 )
+ continue;
+ // iterate through XOR inputs
+ Fanins[0] = Gia_ObjId(p, Gia_Regular(pFan0));
+ Fanins[1] = Gia_ObjId(p, Gia_Regular(pFan1));
+ for ( k = 0; k < 2; k++ )
+ {
+ Entry = Vec_IntEntry( vRanks, Fanins[k] );
+ if ( Entry == Rank ) // the same tree -- allow fanout in this tree
+ continue;
+ if ( Entry == -1 )
+ Vec_IntWriteEntry( vRanks, Fanins[k], Rank );
+ else
+ Vec_IntPush( vDoubles, Fanins[k] );
+ if ( Entry != -1 && Gia_ObjIsAnd(Gia_ManObj(p, Fanins[k])))
+ printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Fanins[k], Entry, Rank );
+ }
+ }
+ // remove duplicated entries
+ Vec_IntForEachEntry( vDoubles, Entry, i )
+ Vec_IntWriteEntry( vRanks, Entry, -1 );
+ Vec_IntFree( vDoubles );
+ return vRanks;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Acec_FindTreeLeaves( Gia_Man_t * p, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks )
+{
+ Vec_Bit_t * vMapXors = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Wec_t * vTreeLeaves = Vec_WecStart( Vec_IntSize(vXorRoots) );
+ Gia_Obj_t * pFan0, * pFan1, * pObj;
+ int i, k, Fanins[2], Rank;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
+ continue;
+ Vec_BitWriteEntry( vMapXors, i, 1 );
+ Rank = Vec_IntEntry( vRanks, i );
+ // skip XORs that are not part of any tree
+ if ( Rank == -1 )
+ continue;
+ // iterate through XOR inputs
+ Fanins[0] = Gia_ObjId(p, Gia_Regular(pFan0));
+ Fanins[1] = Gia_ObjId(p, Gia_Regular(pFan1));
+ for ( k = 0; k < 2; k++ )
+ {
+ if ( Vec_BitEntry(vMapXors, Fanins[k]) )
+ {
+ assert( Rank == Vec_IntEntry(vRanks, Fanins[k]) );
+ continue;
+ }
+ Vec_WecPush( vTreeLeaves, Rank, Fanins[k] );
+ }
+ }
+ Vec_BitFree( vMapXors );
+ return vTreeLeaves;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_FindShadows( Gia_Man_t * p, Vec_Int_t * vRanks )
+{
+ Vec_Int_t * vShadows = Vec_IntDup( vRanks );
+ Gia_Obj_t * pObj; int i, Shad0, Shad1;
+ Gia_ManForEachCi( p, pObj, i )
+ Vec_IntWriteEntry( vShadows, Gia_ObjId(p, pObj), -1 );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( Vec_IntEntry(vShadows, i) >= 0 )
+ continue;
+ Shad0 = Vec_IntEntry(vShadows, Gia_ObjFaninId0(pObj, i));
+ Shad1 = Vec_IntEntry(vShadows, Gia_ObjFaninId1(pObj, i));
+ if ( Shad0 == Shad1 && Shad0 != -1 )
+ Vec_IntWriteEntry(vShadows, i, Shad0);
+ }
+ return vShadows;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_CollectSupp_rec( Gia_Man_t * p, int iNode, int Rank, Vec_Int_t * vRanks )
+{
+ Gia_Obj_t * pObj;
+ int nSize;
+ if ( Gia_ObjIsTravIdCurrentId(p, iNode) )
+ return 0;
+ Gia_ObjSetTravIdCurrentId(p, iNode);
+ pObj = Gia_ManObj(p, iNode);
+ assert( Gia_ObjIsAnd(pObj) );
+ if ( Vec_IntEntry(vRanks, iNode) == Rank )
+ return 1;
+ nSize = Acec_CollectSupp_rec( p, Gia_ObjFaninId0(pObj, iNode), Rank, vRanks );
+ nSize += Acec_CollectSupp_rec( p, Gia_ObjFaninId1(pObj, iNode), Rank, vRanks );
+ return nSize;
+}
+Vec_Wec_t * Acec_FindNexts( Gia_Man_t * p, Vec_Int_t * vRanks, Vec_Int_t * vShadows, Vec_Wec_t * vTreeLeaves )
+{
+ Vec_Wec_t * vNexts = Vec_WecStart( Vec_WecSize(vTreeLeaves) );
+ Vec_Int_t * vTree;
+ int i, k, Node, Fanins[2], Shad0, Shad1, Rank, nSupp;
+ Vec_WecForEachLevel( vTreeLeaves, vTree, i )
+ Vec_IntForEachEntry( vTree, Node, k )
+ {
+ Gia_Obj_t * pObj = Gia_ManObj(p, Node);
+ if ( !Gia_ObjIsAnd(pObj) )
+ continue;
+ Fanins[0] = Gia_ObjFaninId0(pObj, Node);
+ Fanins[1] = Gia_ObjFaninId1(pObj, Node);
+ Shad0 = Vec_IntEntry(vShadows, Fanins[0]);
+ Shad1 = Vec_IntEntry(vShadows, Fanins[1]);
+ if ( Shad0 != Shad1 || Shad0 == -1 )
+ continue;
+ // check support size of Node in terms of the shadow of its fanins
+ Rank = Vec_IntEntry( vRanks, Node );
+ assert( Rank != Shad0 );
+ Gia_ManIncrementTravId( p );
+ nSupp = Acec_CollectSupp_rec( p, Node, Shad0, vRanks );
+ assert( nSupp > 1 );
+ if ( nSupp > 3 )
+ continue;
+ Vec_IntPushUniqueOrder( Vec_WecEntry(vNexts, Shad0), Rank );
+ }
+ return vNexts;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_StructTest( Gia_Man_t * p )
+{
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/acecTree.c b/src/proof/acec/acecTree.c
new file mode 100644
index 00000000..ab17d7b9
--- /dev/null
+++ b/src/proof/acec/acecTree.c
@@ -0,0 +1,783 @@
+/**CFile****************************************************************
+
+ FileName [acecTree.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Adder tree construction.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecTree.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "acecInt.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_BoxFree( Acec_Box_t * pBox )
+{
+ Vec_WecFreeP( &pBox->vAdds );
+ Vec_WecFreeP( &pBox->vLeafLits );
+ Vec_WecFreeP( &pBox->vRootLits );
+ Vec_WecFreeP( &pBox->vUnique );
+ Vec_WecFreeP( &pBox->vShared );
+ ABC_FREE( pBox );
+}
+void Acec_BoxFreeP( Acec_Box_t ** ppBox )
+{
+ if ( *ppBox )
+ Acec_BoxFree( *ppBox );
+ *ppBox = NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_VerifyBoxLeaves( Acec_Box_t * pBox, Vec_Bit_t * vIgnore )
+{
+ Vec_Int_t * vLevel;
+ int i, k, iLit, Count = 0;
+ if ( vIgnore == NULL )
+ return;
+ Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i )
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ if ( Gia_ObjIsAnd(Gia_ManObj(pBox->pGia, Abc_Lit2Var(iLit))) && !Vec_BitEntry(vIgnore, Abc_Lit2Var(iLit)) )
+ printf( "Internal node %d of rank %d is not part of PPG.\n", Abc_Lit2Var(iLit), i ), Count++;
+ printf( "Detected %d suspicious leaves.\n", Count );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Filters trees by removing TFO of roots.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_TreeFilterOne( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree )
+{
+ Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vMarked = Vec_BitStart( Gia_ManObjNum(p) ) ;
+ Gia_Obj_t * pObj;
+ int i, k = 0, Box, Rank;
+ // mark roots
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 );
+ }
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+0), 0 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+1), 0 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+2), 0 );
+ }
+ // iterate through nodes to detect TFO of roots
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( Vec_BitEntry(vIsRoot, Gia_ObjFaninId0(pObj,i)) || Vec_BitEntry(vIsRoot, Gia_ObjFaninId1(pObj,i)) ||
+ Vec_BitEntry(vMarked, Gia_ObjFaninId0(pObj,i)) || Vec_BitEntry(vMarked, Gia_ObjFaninId1(pObj,i)) )
+ Vec_BitWriteEntry( vMarked, i, 1 );
+ }
+ // remove those that overlap with roots
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+ // special case of the first bit
+// if ( i == 0 )
+// continue;
+
+/*
+ if ( Vec_IntEntry(vAdds, 6*Box+3) == 24 && Vec_IntEntry(vAdds, 6*Box+4) == 22 )
+ {
+ printf( "**** removing special one \n" );
+ continue;
+ }
+ if ( Vec_IntEntry(vAdds, 6*Box+3) == 48 && Vec_IntEntry(vAdds, 6*Box+4) == 49 )
+ {
+ printf( "**** removing special one \n" );
+ continue;
+ }
+*/
+ if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) )
+ {
+ printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank );
+ continue;
+ }
+ Vec_IntWriteEntry( vTree, k++, Box );
+ Vec_IntWriteEntry( vTree, k++, Rank );
+ }
+ Vec_IntShrink( vTree, k );
+ Vec_BitFree( vIsRoot );
+ Vec_BitFree( vMarked );
+}
+void Acec_TreeFilterTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees )
+{
+ Vec_Int_t * vLevel;
+ int i;
+ Vec_WecForEachLevel( vTrees, vLevel, i )
+ Acec_TreeFilterOne( p, vAdds, vLevel );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Filters trees by removing TFO of roots.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_TreeMarkTFI_rec( Gia_Man_t * p, int Id, Vec_Bit_t * vMarked )
+{
+ Gia_Obj_t * pObj = Gia_ManObj(p, Id);
+ if ( Vec_BitEntry(vMarked, Id) )
+ return;
+ Vec_BitWriteEntry( vMarked, Id, 1 );
+ if ( !Gia_ObjIsAnd(pObj) )
+ return;
+ Acec_TreeMarkTFI_rec( p, Gia_ObjFaninId0(pObj, Id), vMarked );
+ Acec_TreeMarkTFI_rec( p, Gia_ObjFaninId1(pObj, Id), vMarked );
+}
+void Acec_TreeFilterOne2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree )
+{
+ Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vMarked = Vec_BitStart( Gia_ManObjNum(p) ) ;
+ Gia_Obj_t * pObj;
+ int i, k = 0, Box, Rank;
+ // mark leaves
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 );
+ }
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+3), 0 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4), 0 );
+ }
+ // mark TFI of leaves
+ Gia_ManForEachAnd( p, pObj, i )
+ if ( Vec_BitEntry(vIsLeaf, i) )
+ Acec_TreeMarkTFI_rec( p, i, vMarked );
+ // additional one
+//if ( 10942 < Gia_ManObjNum(p) )
+// Acec_TreeMarkTFI_rec( p, 10942, vMarked );
+ // remove those that overlap with the marked TFI
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+ if ( Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+3)) || Vec_BitEntry(vMarked, Vec_IntEntry(vAdds, 6*Box+4)) )
+ {
+ printf( "Removing box %d=(%d,%d) of rank %d.\n", Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4), Rank );
+ continue;
+ }
+ Vec_IntWriteEntry( vTree, k++, Box );
+ Vec_IntWriteEntry( vTree, k++, Rank );
+ }
+ Vec_IntShrink( vTree, k );
+ Vec_BitFree( vIsLeaf );
+ Vec_BitFree( vMarked );
+}
+void Acec_TreeFilterTrees2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vTrees )
+{
+ Vec_Int_t * vLevel;
+ int i;
+ Vec_WecForEachLevel( vTrees, vLevel, i )
+ Acec_TreeFilterOne2( p, vAdds, vLevel );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_TreeVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ int Truth0, Truth1;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return pObj->Value;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ assert( Gia_ObjIsAnd(pObj) );
+ assert( !Gia_ObjIsXor(pObj) );
+ Truth0 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) );
+ Truth1 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) );
+ Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0;
+ Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1;
+ return (pObj->Value = Truth0 & Truth1);
+}
+void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox )
+{
+ Gia_Obj_t * pObj;
+ unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 };
+ int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0;
+ int fFlip = !fFadd && Acec_SignBit2(vAdds, iBox, 2);
+
+ Gia_ManIncrementTravId( p );
+ for ( k = 0; k < 3; k++ )
+ {
+ iObj = Vec_IntEntry( vAdds, 6*iBox+k );
+ if ( iObj == 0 )
+ continue;
+ pObj = Gia_ManObj( p, iObj );
+ pObj->Value = (Acec_SignBit2(vAdds, iBox, k) ^ fFlip) ? 0xFF & ~Truths[k] : Truths[k];
+ Gia_ObjSetTravIdCurrent( p, pObj );
+ }
+
+ iObj = Vec_IntEntry( vAdds, 6*iBox+3 );
+ TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) );
+ TruthXor = (Acec_SignBit2(vAdds, iBox, 3) ^ fFlip) ? 0xFF & ~TruthXor : TruthXor;
+
+ iObj = Vec_IntEntry( vAdds, 6*iBox+4 );
+ TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) );
+ TruthMaj = (Acec_SignBit2(vAdds, iBox, 4) ^ fFlip) ? 0xFF & ~TruthMaj : TruthMaj;
+
+ if ( fFadd ) // FADD
+ {
+ if ( TruthXor != 0x96 )
+ printf( "Fadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) );
+ if ( TruthMaj != 0xE8 )
+ printf( "Fadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) );
+ }
+ else
+ {
+ //printf( "Sign1 = %d%d%d %d\n", Acec_SignBit(vAdds, iBox, 0), Acec_SignBit(vAdds, iBox, 1), Acec_SignBit(vAdds, iBox, 2), Acec_SignBit(vAdds, iBox, 3) );
+ //printf( "Sign2 = %d%d%d %d%d\n", Acec_SignBit2(vAdds, iBox, 0), Acec_SignBit2(vAdds, iBox, 1), Acec_SignBit2(vAdds, iBox, 2), Acec_SignBit2(vAdds, iBox, 3), Acec_SignBit2(vAdds, iBox, 4) );
+ if ( TruthXor != 0x66 )
+ printf( "Hadd %d sum %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+3 ) );
+ if ( TruthMaj != 0x88 )
+ printf( "Hadd %d carry %d is wrong.\n", iBox, Vec_IntEntry( vAdds, 6*iBox+4 ) );
+ }
+}
+void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes )
+{
+ Vec_Int_t * vLevel;
+ int i, k, Box;
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ Acec_TreeVerifyPhaseOne( p, vAdds, Box );
+}
+void Acec_TreeVerifyPhases2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes )
+{
+ Vec_Bit_t * vPhase = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vRoots = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel;
+ int i, k, n, Box;
+ // mark all output points and their values
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ {
+ Vec_BitWriteEntry( vRoots, Vec_IntEntry( vAdds, 6*Box+3 ), 1 );
+ Vec_BitWriteEntry( vRoots, Vec_IntEntry( vAdds, 6*Box+4 ), 1 );
+ Vec_BitWriteEntry( vPhase, Vec_IntEntry( vAdds, 6*Box+3 ), Acec_SignBit2(vAdds, Box, 3) );
+ Vec_BitWriteEntry( vPhase, Vec_IntEntry( vAdds, 6*Box+4 ), Acec_SignBit2(vAdds, Box, 4) );
+ }
+ // compare with input points
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ for ( n = 0; n < 3; n++ )
+ {
+ if ( !Vec_BitEntry(vRoots, Vec_IntEntry(vAdds, 6*Box+n)) )
+ continue;
+ if ( Vec_BitEntry(vPhase, Vec_IntEntry(vAdds, 6*Box+n)) == Acec_SignBit2(vAdds, Box, n) )
+ continue;
+ printf( "Phase of input %d=%d is mismatched in box %d=(%d,%d).\n",
+ n, Vec_IntEntry(vAdds, 6*Box+n), Box, Vec_IntEntry(vAdds, 6*Box+3), Vec_IntEntry(vAdds, 6*Box+4) );
+ }
+ Vec_BitFree( vPhase );
+ Vec_BitFree( vRoots );
+}
+void Acec_TreeVerifyConnections( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes )
+{
+ Vec_Int_t * vCounts = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel;
+ int i, k, n, Box;
+ // mark outputs
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ {
+ Vec_IntWriteEntry( vCounts, Vec_IntEntry( vAdds, 6*Box+3 ), 0 );
+ Vec_IntWriteEntry( vCounts, Vec_IntEntry( vAdds, 6*Box+4 ), 0 );
+ }
+ // count fanouts
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ for ( n = 0; n < 3; n++ )
+ if ( Vec_IntEntry( vCounts, Vec_IntEntry(vAdds, 6*Box+n) ) != -1 )
+ Vec_IntAddToEntry( vCounts, Vec_IntEntry(vAdds, 6*Box+n), 1 );
+ // print out
+ printf( "The adder tree has %d internal cut points. ", Vec_IntCountLarger(vCounts, -1) );
+ if ( Vec_IntCountLarger(vCounts, 1) == 0 )
+ printf( "There is no internal fanouts.\n" );
+ else
+ {
+ printf( "These %d points have more than one fanout:\n", Vec_IntCountLarger(vCounts, 1) );
+ Vec_IntForEachEntry( vCounts, Box, i )
+ if ( Box > 1 )
+ printf( "Node %d(lev %d) has fanout %d.\n", i, Gia_ObjLevelId(p, i), Box );
+ }
+ Vec_IntFree( vCounts );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates polarity.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes )
+{
+ Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel;
+ int i, k, Box;
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box );
+ return vMap;
+}
+void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, Vec_Bit_t * vVisit )
+{
+ int k, iBox, iXor, fXorPhase, fPhaseThis;
+ assert( Node != 0 );
+ iBox = Vec_IntEntry( vMap, Node );
+ if ( iBox == -1 )
+ return;
+ assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) );
+ if ( Vec_BitEntry(vVisit, iBox) )
+ return;
+ Vec_BitWriteEntry( vVisit, iBox, 1 );
+ iXor = Vec_IntEntry( vAdds, 6*iBox+3 );
+ fXorPhase = Acec_SignBit(vAdds, iBox, 3);
+ if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 )
+ {
+ //fPhaseThis = Acec_SignBit( vAdds, iBox, 2 ) ^ fPhase;
+ //fXorPhase ^= fPhaseThis;
+ //Acec_SignSetBit2( vAdds, iBox, 2, fPhaseThis ); // complemented HADD -- create const1 input
+ fPhase ^= Acec_SignBit( vAdds, iBox, 2 );
+ fXorPhase ^= fPhase;
+ Acec_SignSetBit2( vAdds, iBox, 2, fPhase ); // complemented HADD -- create const1 input
+ }
+ for ( k = 0; k < 3; k++ )
+ {
+ int iObj = Vec_IntEntry( vAdds, 6*iBox+k );
+ if ( iObj == 0 )
+ continue;
+ fPhaseThis = Acec_SignBit(vAdds, iBox, k) ^ fPhase;
+ fXorPhase ^= fPhaseThis;
+ Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vVisit );
+ Acec_SignSetBit2( vAdds, iBox, k, fPhaseThis );
+ }
+ Acec_SignSetBit2( vAdds, iBox, 3, fXorPhase );
+ Acec_SignSetBit2( vAdds, iBox, 4, fPhase );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find internal cut points with exactly one adder fanin/fanout.]
+
+ Description [Returns a map of point into its input/output adder.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_TreeAddInOutPoint( Vec_Int_t * vMap, int iObj, int iAdd, int fOut )
+{
+ int * pPlace = Vec_IntEntryP( vMap, Abc_Var2Lit(iObj, fOut) );
+ if ( *pPlace == -1 )
+ *pPlace = iAdd;
+ else if ( *pPlace >= 0 )
+ *pPlace = -2;
+}
+Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore )
+{
+ Vec_Int_t * vMap = Vec_IntStartFull( 2*Gia_ManObjNum(p) );
+ int i;
+ for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
+ {
+ if ( vIgnore && (Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+3)) || Vec_BitEntry(vIgnore, Vec_IntEntry(vAdds, 6*i+4))) )
+ continue;
+ Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 );
+ Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 );
+ Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+2), i, 0 );
+ Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+3), i, 1 );
+ Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+4), i, 1 );
+ }
+ return vMap;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find adder trees as groups of adders connected vis cut-points.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acec_TreeWhichPoint( Vec_Int_t * vAdds, int iAdd, int iObj )
+{
+ int k;
+ for ( k = 0; k < 5; k++ )
+ if ( Vec_IntEntry(vAdds, 6*iAdd+k) == iObj )
+ return k;
+ assert( 0 );
+ return -1;
+}
+void Acec_TreeFindTrees2_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iAdd, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound )
+{
+ extern void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound );
+ int k;
+ if ( Vec_BitEntry(vFound, iAdd) )
+ return;
+ Vec_BitWriteEntry( vFound, iAdd, 1 );
+ Vec_IntPush( vTree, iAdd );
+ Vec_IntPush( vTree, Rank );
+ //printf( "Assigning rank %d to (%d:%d).\n", Rank, Vec_IntEntry(vAdds, 6*iAdd+3), Vec_IntEntry(vAdds, 6*iAdd+4) );
+ for ( k = 0; k < 5; k++ )
+ Acec_TreeFindTrees_rec( vAdds, vMap, Vec_IntEntry(vAdds, 6*iAdd+k), k == 4 ? Rank + 1 : Rank, vTree, vFound );
+}
+void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound )
+{
+ int In = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 1) );
+ int Out = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 0) );
+ if ( In < 0 || Out < 0 )
+ return;
+ Acec_TreeFindTrees2_rec( vAdds, vMap, In, Acec_TreeWhichPoint(vAdds, In, iObj) == 4 ? Rank-1 : Rank, vTree, vFound );
+ Acec_TreeFindTrees2_rec( vAdds, vMap, Out, Rank, vTree, vFound );
+}
+Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut )
+{
+ Vec_Wec_t * vTrees = Vec_WecAlloc( 10 );
+ Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds, vIgnore );
+ Vec_Bit_t * vFound = Vec_BitStart( Vec_IntSize(vAdds)/6 );
+ Vec_Int_t * vTree;
+ int i, k, In, Out, Box, Rank, MinRank;
+ // go through the cut-points
+ Vec_IntForEachEntryDouble( vMap, In, Out, i )
+ {
+ if ( In < 0 || Out < 0 )
+ continue;
+ assert( Vec_BitEntry(vFound, In) == Vec_BitEntry(vFound, Out) );
+ if ( Vec_BitEntry(vFound, In) )
+ continue;
+ vTree = Vec_WecPushLevel( vTrees );
+ Acec_TreeFindTrees_rec( vAdds, vMap, i/2, 0, vTree, vFound );
+ // normalize rank
+ MinRank = ABC_INFINITY;
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, k )
+ MinRank = Abc_MinInt( MinRank, Rank );
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, k )
+ Vec_IntWriteEntry( vTree, k+1, Rank - MinRank );
+ }
+ Vec_BitFree( vFound );
+ Vec_IntFree( vMap );
+ // filter trees
+ if ( fFilterIn )
+ Acec_TreeFilterTrees2( p, vAdds, vTrees );
+ else if ( fFilterOut )
+ Acec_TreeFilterTrees( p, vAdds, vTrees );
+ // sort by size
+ Vec_WecSort( vTrees, 1 );
+ return vTrees;
+}
+void Acec_TreeFindTreesTest( Gia_Man_t * p )
+{
+ Vec_Wec_t * vTrees;
+
+ abctime clk = Abc_Clock();
+ Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
+ int nFadds = Ree_ManCountFadds( vAdds );
+ printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ clk = Abc_Clock();
+ vTrees = Acec_TreeFindTrees( p, vAdds, NULL, 0, 0 );
+ printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ Vec_WecPrint( vTrees, 0 );
+
+ Vec_WecFree( vTrees );
+ Vec_IntFree( vAdds );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Derives one adder tree.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+`
+***********************************************************************/
+void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds )
+{
+ Vec_Int_t * vLevel;
+ int i, k, iBox;
+ Vec_WecForEachLevel( vBoxes, vLevel, i )
+ {
+ printf( " %4d : %2d {", i, Vec_IntSize(vLevel) );
+ Vec_IntForEachEntry( vLevel, iBox, k )
+ {
+ printf( " %s%d=(%d,%d)", Vec_IntEntry(vAdds, 6*iBox+2) == 0 ? "*":"", iBox,
+ Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) );
+ //printf( "(%d,%d,%d)", Vec_IntEntry(vAdds, 6*iBox+0), Vec_IntEntry(vAdds, 6*iBox+1), Vec_IntEntry(vAdds, 6*iBox+2) );
+ }
+ printf( " }\n" );
+ }
+}
+void Acec_TreePrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds )
+{
+ printf( "Adders:\n" );
+ Acec_PrintAdders( pBox->vAdds, vAdds );
+ printf( "Inputs:\n" );
+ Vec_WecPrintLits( pBox->vLeafLits );
+ printf( "Outputs:\n" );
+ Vec_WecPrintLits( pBox->vRootLits );
+// printf( "Node %d has level %d.\n", 3715, Gia_ObjLevelId(pBox->pGia, 3715) );
+// printf( "Node %d has level %d.\n", 167, Gia_ObjLevelId(pBox->pGia, 167) );
+// printf( "Node %d has level %d.\n", 278, Gia_ObjLevelId(pBox->pGia, 278) );
+// printf( "Node %d has level %d.\n", 597, Gia_ObjLevelId(pBox->pGia, 597) );
+}
+
+int Acec_CreateBoxMaxRank( Vec_Int_t * vTree )
+{
+ int k, Box, Rank, MaxRank = 0;
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, k )
+ MaxRank = Abc_MaxInt( MaxRank, Rank );
+ return MaxRank;
+}
+Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree )
+{
+ int MaxRank = Acec_CreateBoxMaxRank(vTree);
+ Vec_Bit_t * vVisit = Vec_BitStart( Vec_IntSize(vAdds)/6 );
+ Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel, * vMap;
+ int i, j, k, Box, Rank;//, Count = 0;
+
+ Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 );
+ pBox->pGia = p;
+ pBox->vAdds = Vec_WecStart( MaxRank + 1 );
+ pBox->vLeafLits = Vec_WecStart( MaxRank + 1 );
+ pBox->vRootLits = Vec_WecStart( MaxRank + 2 );
+
+ // collect boxes; mark inputs/outputs
+ Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
+ {
+// if ( 37 == Box && 6 == Rank )
+// {
+// printf( "Skipping one adder...\n" );
+// continue;
+// }
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 );
+ Vec_WecPush( pBox->vAdds, Rank, Box );
+ }
+ // sort each level
+ Vec_WecForEachLevel( pBox->vAdds, vLevel, i )
+ Vec_IntSort( vLevel, 0 );
+
+ // set phases starting from roots
+ vMap = Acec_TreeCarryMap( p, vAdds, pBox->vAdds );
+ Vec_WecForEachLevelReverse( pBox->vAdds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) )
+ {
+ //printf( "Pushing phase of output %d of box %d\n", Vec_IntEntry(vAdds, 6*Box+4), Box );
+ Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0, vVisit );
+ }
+ Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds );
+ Acec_TreeVerifyPhases2( p, vAdds, pBox->vAdds );
+ Vec_BitFree( vVisit );
+ Vec_IntFree( vMap );
+
+ // collect inputs/outputs
+ Vec_BitWriteEntry( vIsRoot, 0, 1 );
+ Vec_WecForEachLevel( pBox->vAdds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, j )
+ {
+ for ( k = 0; k < 3; k++ )
+ if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) )
+ Vec_WecPush( pBox->vLeafLits, i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) );
+ for ( k = 3; k < 5; k++ )
+ if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) )
+ {
+ //if ( Vec_IntEntry(vAdds, 6*Box+k) == 10942 )
+ //{
+ // printf( "++++++++++++ Skipping special\n" );
+ // continue;
+ //}
+ Vec_WecPush( pBox->vRootLits, k == 4 ? i + 1 : i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) );
+ }
+ if ( Vec_IntEntry(vAdds, 6*Box+2) == 0 && Acec_SignBit2(vAdds, Box, 2) )
+ Vec_WecPush( pBox->vLeafLits, i, 1 );
+ }
+ Vec_BitFree( vIsLeaf );
+ Vec_BitFree( vIsRoot );
+ // sort each level
+ Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i )
+ Vec_IntSort( vLevel, 0 );
+ Vec_WecForEachLevel( pBox->vRootLits, vLevel, i )
+ Vec_IntSort( vLevel, 1 );
+ //return pBox;
+/*
+ // push literals forward
+ //Vec_WecPrint( pBox->vLeafLits, 0 );
+ Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i )
+ {
+ int This, Prev = Vec_IntEntry(vLevel, 0);
+ Vec_IntForEachEntryStart( vLevel, This, j, 1 )
+ {
+ if ( Prev != This )
+ {
+ Prev = This;
+ continue;
+ }
+ if ( i+1 >= Vec_WecSize(pBox->vLeafLits) )
+ continue;
+ Vec_IntPushOrder( Vec_WecEntry(pBox->vLeafLits, i+1), This );
+ Vec_IntDrop( vLevel, j-- );
+ Vec_IntDrop( vLevel, j-- );
+ Prev = -1;
+ Count++;
+ }
+ }
+ printf( "Pushed forward %d input literals.\n", Count );
+*/
+ //Vec_WecPrint( pBox->vLeafLits, 0 );
+ return pBox;
+}
+void Acec_CreateBoxTest( Gia_Man_t * p )
+{
+ Acec_Box_t * pBox;
+ Vec_Wec_t * vTrees;
+ Vec_Int_t * vTree;
+
+ abctime clk = Abc_Clock();
+ Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
+ int i, nFadds = Ree_ManCountFadds( vAdds );
+ printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ clk = Abc_Clock();
+ vTrees = Acec_TreeFindTrees( p, vAdds, NULL, 0, 0 );
+ printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ //Vec_WecPrint( vTrees, 0 );
+
+ Vec_WecForEachLevel( vTrees, vTree, i )
+ {
+ pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, i) );
+ printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n",
+ i, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds),
+ Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) );
+ Acec_TreePrintBox( pBox, vAdds );
+ Acec_BoxFreeP( &pBox );
+ }
+
+ Vec_WecFree( vTrees );
+ Vec_IntFree( vAdds );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, Vec_Bit_t * vIgnore, int fFilterIn, int fFilterOut, int fVerbose )
+{
+ Acec_Box_t * pBox = NULL;
+ Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose );
+ Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds, vIgnore, fFilterIn, fFilterOut );
+ if ( vTrees && Vec_WecSize(vTrees) > 0 )
+ {
+ pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) );
+ Acec_VerifyBoxLeaves( pBox, vIgnore );
+ }
+ if ( pBox )//&& fVerbose )
+ printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n",
+ 0, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds),
+ Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) );
+ if ( pBox && fVerbose )
+ Acec_TreePrintBox( pBox, vAdds );
+ //Acec_PrintAdders( pBox0->vAdds, vAdds );
+ //Acec_MultDetectInputs( p, pBox->vLeafLits, pBox->vRootLits );
+ Vec_WecFreeP( &vTrees );
+ Vec_IntFree( vAdds );
+ return pBox;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/acecUtil.c b/src/proof/acec/acecUtil.c
index 191856cf..be12afef 100644
--- a/src/proof/acec/acecUtil.c
+++ b/src/proof/acec/acecUtil.c
@@ -90,6 +90,29 @@ void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose )
Vec_IntFree( vXors );
}
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupTopMostRange( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ Vec_Int_t * vTops = Vec_IntAlloc( 10 );
+ int i;
+ for ( i = 45; i < 52; i++ )
+ Vec_IntPush( vTops, Gia_ObjId( p, Gia_ObjFanin0(Gia_ManCo(p, i)) ) );
+ pNew = Gia_ManDupAndConesLimit( p, Vec_IntArray(vTops), Vec_IntSize(vTops), 100 );
+ Vec_IntFree( vTops );
+ return pNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/acec/acecXor.c b/src/proof/acec/acecXor.c
new file mode 100644
index 00000000..71e0b7b3
--- /dev/null
+++ b/src/proof/acec/acecXor.c
@@ -0,0 +1,434 @@
+/**CFile****************************************************************
+
+ FileName [acecXor.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Detection of XOR trees.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecXor.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "acecInt.h"
+#include "misc/vec/vecWec.h"
+#include "misc/extra/extra.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acec_CheckXors( Gia_Man_t * p, Vec_Int_t * vXors )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ Vec_Int_t * vCount2 = Vec_IntAlloc( Gia_ManObjNum(p) );
+ int i, Entry, Count = 0;
+ for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
+ if ( Vec_IntEntry(vXors, 4*i+3) == 0 )
+ Vec_IntAddToEntry( vCount2, Vec_IntEntry(vXors, 4*i), 1 );
+ Vec_IntForEachEntry( vCount2, Entry, i )
+ if ( Entry > 1 )
+ printf( "*** Obj %d has %d two-input XOR cuts.\n", i, Entry ), Count++;
+ else if ( Entry == 1 && Gia_ObjRecognizeExor(Gia_ManObj(p, i), &pFan0, &pFan1) )
+ printf( "*** Obj %d cannot be recognized as XOR.\n", i );
+ if ( Count == 0 )
+ printf( "*** There no multiple two-input XOR cuts.\n" );
+ Vec_IntFree( vCount2 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Acec_OrderTreeRoots( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks )
+{
+ Vec_Int_t * vOrder = Vec_IntAlloc( Vec_IntSize(vXorRoots) );
+ Vec_Int_t * vMove = Vec_IntStartFull( Vec_IntSize(vXorRoots) );
+ int i, k, Entry, This;
+ // iterate through adders and for each try mark the next one
+ for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
+ {
+ int Node = Vec_IntEntry(vAdds, 6*i+4);
+ if ( Vec_IntEntry(vRanks, Node) == -1 )
+ continue;
+ for ( k = 0; k < 3; k++ )
+ {
+ int Fanin = Vec_IntEntry(vAdds, 6*i+k);
+ if ( Vec_IntEntry(vRanks, Fanin) == -1 )
+ continue;
+ //printf( "%4d: %2d -> %2d\n", Node, Vec_IntEntry(vRanks, Node), Vec_IntEntry(vRanks, Fanin) );
+ Vec_IntWriteEntry( vMove, Vec_IntEntry(vRanks, Node), Vec_IntEntry(vRanks, Fanin) );
+ }
+ }
+//Vec_IntPrint( vMove );
+ // find reodering
+ Vec_IntForEachEntry( vMove, Entry, i )
+ if ( Entry == -1 && Vec_IntFind(vMove, i) >= 0 )
+ break;
+ assert( i < Vec_IntSize(vMove) );
+ while ( 1 )
+ {
+ Vec_IntPush( vOrder, Vec_IntEntry(vXorRoots, i) );
+ Entry = i;
+ Vec_IntForEachEntry( vMove, This, i )
+ if ( This == Entry )
+ break;
+ if ( i == Vec_IntSize(vMove) )
+ break;
+ }
+ Vec_IntFree( vMove );
+//Vec_IntPrint( vOrder );
+ return vOrder;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+// marks XOR outputs
+Vec_Bit_t * Acec_MapXorOuts( Gia_Man_t * p, Vec_Int_t * vXors )
+{
+ Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i;
+ for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
+ Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i), 1 );
+ return vMap;
+}
+// marks XOR outputs participating in trees
+Vec_Bit_t * Acec_MapXorOuts2( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vRanks )
+{
+ Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i;
+ for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
+ if ( Vec_IntEntry(vRanks, Vec_IntEntry(vXors, 4*i)) != -1 )
+ Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i), 1 );
+ return vMap;
+}
+// marks MAJ outputs
+Vec_Bit_t * Acec_MapMajOuts( Gia_Man_t * p, Vec_Int_t * vAdds )
+{
+ Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i;
+ for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
+ Vec_BitWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), 1 );
+ return vMap;
+}
+// marks MAJ outputs participating in trees
+Vec_Int_t * Acec_MapMajOuts2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vRanks )
+{
+ Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); int i;
+ for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
+ if ( Vec_IntEntry(vRanks, Vec_IntEntry(vAdds, 6*i+4)) != -1 )
+ Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*i+4), i );
+ return vMap;
+}
+// marks nodes appearing as fanins to XORs
+Vec_Bit_t * Acec_MapXorIns( Gia_Man_t * p, Vec_Int_t * vXors )
+{
+ Vec_Bit_t * vMap = Vec_BitStart( Gia_ManObjNum(p) ); int i;
+ for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
+ {
+ Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+1), 1 );
+ Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+2), 1 );
+ Vec_BitWriteEntry( vMap, Vec_IntEntry(vXors, 4*i+3), 1 );
+ }
+ return vMap;
+}
+// collects XOR roots (XOR nodes not appearing as fanins of other XORs)
+Vec_Int_t * Acec_FindXorRoots( Gia_Man_t * p, Vec_Int_t * vXors )
+{
+ Vec_Bit_t * vMapXorIns = Acec_MapXorIns( p, vXors );
+ Vec_Int_t * vXorRoots = Vec_IntAlloc( 100 ); int i;
+ for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
+ if ( !Vec_BitEntry(vMapXorIns, Vec_IntEntry(vXors, 4*i)) )
+ Vec_IntPushUniqueOrder( vXorRoots, Vec_IntEntry(vXors, 4*i) );
+ Vec_BitFree( vMapXorIns );
+ return vXorRoots;
+}
+// collects XOR trees belonging to each of XOR roots
+Vec_Int_t * Acec_RankTrees( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vXorRoots )
+{
+ Vec_Int_t * vDoubles = Vec_IntAlloc( 100 );
+ int i, k, Entry;
+ // map roots into their ranks
+ Vec_Int_t * vRanks = Vec_IntStartFull( Gia_ManObjNum(p) );
+ Vec_IntForEachEntry( vXorRoots, Entry, i )
+ Vec_IntWriteEntry( vRanks, Entry, i );
+ // map nodes into their ranks
+ for ( i = Vec_IntSize(vXors)/4 - 1; i >= 0; i-- )
+ {
+ int Root = Vec_IntEntry( vXors, 4*i );
+ int Rank = Vec_IntEntry( vRanks, Root );
+ // skip XORs that are not part of any tree
+ if ( Rank == -1 )
+ continue;
+ // iterate through XOR inputs
+ for ( k = 1; k < 4; k++ )
+ {
+ int Node = Vec_IntEntry( vXors, 4*i+k );
+ if ( Node == 0 ) // HA
+ continue;
+ Entry = Vec_IntEntry( vRanks, Node );
+ if ( Entry == Rank ) // the same tree
+ continue;
+ if ( Entry == -1 )
+ Vec_IntWriteEntry( vRanks, Node, Rank );
+ else
+ Vec_IntPush( vDoubles, Node );
+
+ if ( Entry != -1 && Gia_ObjIsAnd(Gia_ManObj(p, Node)))
+ printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Node, Entry, Rank );
+ }
+ }
+ // remove duplicated entries
+ Vec_IntForEachEntry( vDoubles, Entry, i )
+ Vec_IntWriteEntry( vRanks, Entry, -1 );
+ Vec_IntFree( vDoubles );
+ return vRanks;
+}
+// collects leaves of each XOR tree
+Vec_Wec_t * Acec_FindXorLeaves( Gia_Man_t * p, Vec_Int_t * vXors, Vec_Int_t * vAdds, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks, Vec_Wec_t ** pvAddBoxes )
+{
+ Vec_Bit_t * vMapXors = Acec_MapXorOuts2( p, vXors, vRanks );
+ Vec_Int_t * vMapMajs = Acec_MapMajOuts2( p, vAdds, vRanks );
+ Vec_Wec_t * vXorLeaves = Vec_WecStart( Vec_IntSize(vXorRoots) );
+ Vec_Wec_t * vAddBoxes = Vec_WecStart( Vec_IntSize(vXorRoots) );
+ int i, k;
+ for ( i = 0; 4*i < Vec_IntSize(vXors); i++ )
+ {
+ int Xor = Vec_IntEntry(vXors, 4*i);
+ int Rank = Vec_IntEntry(vRanks, Xor);
+ if ( Rank == -1 )
+ continue;
+ for ( k = 1; k < 4; k++ )
+ {
+ int Fanin = Vec_IntEntry(vXors, 4*i+k);
+ //int RankFanin = Vec_IntEntry(vRanks, Fanin);
+ if ( Fanin == 0 )
+ continue;
+ if ( Vec_BitEntry(vMapXors, Fanin) )
+ {
+ assert( Rank == Vec_IntEntry(vRanks, Fanin) );
+ continue;
+ }
+// if ( Vec_BitEntry(vMapXors, Fanin) && Rank == RankFanin )
+// continue;
+ if ( Vec_IntEntry(vMapMajs, Fanin) == -1 ) // no adder driving this input
+ Vec_WecPush( vXorLeaves, Rank, Fanin );
+ else if ( Vec_IntEntry(vRanks, Xor) > 0 ) // save adder box
+ Vec_WecPush( vAddBoxes, Rank-1, Vec_IntEntry(vMapMajs, Fanin) );
+ }
+ }
+ Vec_BitFree( vMapXors );
+ Vec_IntFree( vMapMajs );
+ if ( pvAddBoxes )
+ *pvAddBoxes = vAddBoxes;
+ return vXorLeaves;
+}
+void Acec_CheckBoothPPs( Gia_Man_t * p, Vec_Wec_t * vLitLeaves )
+{
+ Vec_Bit_t * vMarked = Acec_MultMarkPPs( p );
+ Vec_Int_t * vLevel;
+ int i, k, iLit;
+ Vec_WecForEachLevel( vLitLeaves, vLevel, i )
+ {
+ int CountPI = 0, CountB = 0, CountNB = 0;
+ Vec_IntForEachEntry( vLevel, iLit, k )
+ if ( !Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(iLit))) )
+ CountPI++;
+ else if ( Vec_BitEntry( vMarked, Abc_Lit2Var(iLit) ) )
+ CountB++;
+ else
+ CountNB++;
+
+ printf( "Rank %2d : Lits = %5d PI = %d Booth = %5d Non-Booth = %5d\n", i, Vec_IntSize(vLevel), CountPI, CountB, CountNB );
+ }
+ Vec_BitFree( vMarked );
+}
+Acec_Box_t * Acec_FindBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vAddBoxes, Vec_Wec_t * vXorLeaves, Vec_Int_t * vXorRoots )
+{
+ extern Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes );
+ extern void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase, Vec_Bit_t * vVisit );
+ extern void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes );
+ extern void Acec_TreeVerifyPhases2( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes );
+
+ int MaxRank = Vec_WecSize( vAddBoxes );
+ Vec_Bit_t * vVisit = Vec_BitStart( Vec_IntSize(vAdds)/6 );
+ Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Int_t * vLevel, * vLevel2, * vMap;
+ int i, j, k, Box, Node;
+
+ Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 );
+ pBox->pGia = p;
+ pBox->vAdds = vAddBoxes; // Vec_WecDup( vAddBoxes );
+ pBox->vLeafLits = Vec_WecStart( MaxRank + 0 );
+ pBox->vRootLits = Vec_WecStart( MaxRank + 0 );
+
+ assert( Vec_WecSize(vAddBoxes) == Vec_WecSize(vXorLeaves) );
+ assert( Vec_WecSize(vAddBoxes) == Vec_IntSize(vXorRoots) );
+
+ // collect boxes; mark inputs/outputs
+ Vec_WecForEachLevel( pBox->vAdds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ {
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 );
+ Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 );
+ Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 );
+ }
+ // sort each level
+ Vec_WecForEachLevel( pBox->vAdds, vLevel, i )
+ Vec_IntSort( vLevel, 0 );
+
+ // set phases starting from roots
+ vMap = Acec_TreeCarryMap( p, vAdds, pBox->vAdds );
+ Vec_WecForEachLevelReverse( pBox->vAdds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, k )
+ if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+4) ) )
+ {
+ //printf( "Pushing phase of output %d of box %d\n", Vec_IntEntry(vAdds, 6*Box+4), Box );
+ Acec_TreePhases_rec( p, vAdds, vMap, Vec_IntEntry(vAdds, 6*Box+4), Vec_IntEntry(vAdds, 6*Box+2) != 0, vVisit );
+ }
+ Acec_TreeVerifyPhases( p, vAdds, pBox->vAdds );
+ Acec_TreeVerifyPhases2( p, vAdds, pBox->vAdds );
+ Vec_BitFree( vVisit );
+ Vec_IntFree( vMap );
+
+ // collect inputs/outputs
+ Vec_BitWriteEntry( vIsRoot, 0, 1 );
+ Vec_WecForEachLevel( pBox->vAdds, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Box, j )
+ {
+ for ( k = 0; k < 3; k++ )
+ if ( !Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) )
+ Vec_WecPush( pBox->vLeafLits, i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) );
+ for ( k = 3; k < 5; k++ )
+ if ( !Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) )
+ Vec_WecPush( pBox->vRootLits, k == 4 ? i + 1 : i, Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), Acec_SignBit2(vAdds, Box, k)) );
+ if ( Vec_IntEntry(vAdds, 6*Box+2) == 0 && Acec_SignBit2(vAdds, Box, 2) )
+ Vec_WecPush( pBox->vLeafLits, i, 1 );
+ }
+ Vec_BitFree( vIsLeaf );
+ Vec_BitFree( vIsRoot );
+
+ // collect last bit
+ vLevel = Vec_WecEntry( pBox->vLeafLits, Vec_WecSize(pBox->vLeafLits)-1 );
+ vLevel2 = Vec_WecEntry( vXorLeaves, Vec_WecSize(vXorLeaves)-1 );
+ if ( Vec_IntSize(vLevel) == 0 && Vec_IntSize(vLevel2) > 0 )
+ {
+ Vec_IntForEachEntry( vLevel2, Node, k )
+ Vec_IntPush( vLevel, Abc_Var2Lit(Node, 0) );
+ }
+ vLevel = Vec_WecEntry( pBox->vRootLits, Vec_WecSize(pBox->vRootLits)-1 );
+ Vec_IntFill( vLevel, 1, Abc_Var2Lit(Vec_IntEntryLast(vXorRoots), 0) );
+
+ // sort each level
+ Vec_WecForEachLevel( pBox->vLeafLits, vLevel, i )
+ Vec_IntSort( vLevel, 0 );
+ Vec_WecForEachLevel( pBox->vRootLits, vLevel, i )
+ Vec_IntSort( vLevel, 1 );
+
+ //Acec_CheckBoothPPs( p, pBox->vLeafLits );
+ return pBox;
+}
+
+Acec_Box_t * Acec_ProduceBox( Gia_Man_t * p, int fVerbose )
+{
+ extern void Acec_TreeVerifyConnections( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes );
+
+ abctime clk = Abc_Clock();
+ Acec_Box_t * pBox = NULL;
+ Vec_Int_t * vXors, * vAdds = Ree_ManComputeCuts( p, &vXors, 0 );
+ Vec_Int_t * vTemp, * vXorRoots = Acec_FindXorRoots( p, vXors );
+ Vec_Int_t * vRanks = Acec_RankTrees( p, vXors, vXorRoots );
+ Vec_Wec_t * vXorLeaves, * vAddBoxes = NULL;
+
+ Gia_ManLevelNum(p);
+
+ //Acec_CheckXors( p, vXors );
+
+ //Ree_ManPrintAdders( vAdds, 1 );
+ if ( fVerbose )
+ printf( "Detected %d full-adders and %d half-adders. Found %d XOR-cuts. ", Ree_ManCountFadds(vAdds), Vec_IntSize(vAdds)/6-Ree_ManCountFadds(vAdds), Vec_IntSize(vXors)/4 );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+
+ vXorRoots = Acec_OrderTreeRoots( p, vAdds, vTemp = vXorRoots, vRanks );
+ Vec_IntFree( vTemp );
+ Vec_IntFree( vRanks );
+
+ vRanks = Acec_RankTrees( p, vXors, vXorRoots );
+ vXorLeaves = Acec_FindXorLeaves( p, vXors, vAdds, vXorRoots, vRanks, &vAddBoxes );
+ Vec_IntFree( vRanks );
+
+ //printf( "XOR roots after reordering: \n" );
+ //Vec_IntPrint( vXorRoots );
+ //printf( "XOR leaves: \n" );
+ //Vec_WecPrint( vXorLeaves, 0 );
+ //printf( "Adder boxes: \n" );
+ //Vec_WecPrint( vAddBoxes, 0 );
+
+ Acec_TreeVerifyConnections( p, vAdds, vAddBoxes );
+
+ pBox = Acec_FindBox( p, vAdds, vAddBoxes, vXorLeaves, vXorRoots );
+ //Vec_WecFree( vAddBoxes );
+
+ if ( fVerbose )
+ Acec_TreePrintBox( pBox, vAdds );
+
+ Vec_IntFree( vXorRoots );
+ Vec_WecFree( vXorLeaves );
+
+ Vec_IntFree( vXors );
+ Vec_IntFree( vAdds );
+
+ return pBox;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make
index df6db695..f4c69892 100644
--- a/src/proof/acec/module.make
+++ b/src/proof/acec/module.make
@@ -1,13 +1,18 @@
SRC += src/proof/acec/acecCl.c \
src/proof/acec/acecCore.c \
src/proof/acec/acecCo.c \
+ src/proof/acec/acecBo.c \
src/proof/acec/acecRe.c \
src/proof/acec/acecPa.c \
src/proof/acec/acecPo.c \
src/proof/acec/acecPool.c \
src/proof/acec/acecCover.c \
src/proof/acec/acecFadds.c \
+ src/proof/acec/acecMult.c \
+ src/proof/acec/acecNorm.c \
src/proof/acec/acecOrder.c \
src/proof/acec/acecPolyn.c \
src/proof/acec/acecSt.c \
- src/proof/acec/acecUtil.c
+ src/proof/acec/acecTree.c \
+ src/proof/acec/acecUtil.c \
+ src/proof/acec/acecXor.c
diff --git a/src/proof/cec/cecCec.c b/src/proof/cec/cecCec.c
index 77a6ed4a..be6df65f 100644
--- a/src/proof/cec/cecCec.c
+++ b/src/proof/cec/cecCec.c
@@ -85,7 +85,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime
{
if ( !fSilent )
{
- Abc_Print( 1, "Networks are equivalent. " );
+ Abc_Print( 1, "Networks are equivalent. " );
Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal );
}
}
@@ -93,7 +93,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime
{
if ( !fSilent )
{
- Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
+ Abc_Print( 1, "Networks are NOT EQUIVALENT. " );
Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal );
}
if ( pMiterCec->pData == NULL )
@@ -120,7 +120,7 @@ int Cec_ManVerifyOld( Gia_Man_t * pMiter, int fVerbose, int * piOutFail, abctime
}
else if ( !fSilent )
{
- Abc_Print( 1, "Networks are UNDECIDED. " );
+ Abc_Print( 1, "Networks are UNDECIDED. " );
Abc_PrintTime( 1, "Time", Abc_Clock() - clkTotal );
}
fflush( stdout );
@@ -225,8 +225,7 @@ int Cec_ManHandleSpecialCases( Gia_Man_t * p, Cec_ParCec_t * pPars )
***********************************************************************/
int Cec_ManVerifyNaive( Gia_Man_t * p, Cec_ParCec_t * pPars )
{
- extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
Gia_Obj_t * pObj0, * pObj1;
abctime clkStart = Abc_Clock();
diff --git a/src/proof/cec/cecSat.c b/src/proof/cec/cecSat.c
new file mode 100644
index 00000000..97bbb7d3
--- /dev/null
+++ b/src/proof/cec/cecSat.c
@@ -0,0 +1,1003 @@
+/**CFile****************************************************************
+
+ FileName [cecSat.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Detection of structural isomorphism.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "aig/gia/gia.h"
+#include "misc/util/utilTruth.h"
+#include "sat/satoko/satoko.h"
+#include "sat/satoko/solver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// sweeping manager
+typedef struct Cec2_Par_t_ Cec2_Par_t;
+struct Cec2_Par_t_
+{
+ int nSimWords; // simulation words
+ int nSimRounds; // simulation rounds
+ int nConfLimit; // SAT solver conflict limit
+ int fIsMiter; // this is a miter
+ int fUseCones; // use logic cones
+ int fVeryVerbose; // verbose stats
+ int fVerbose; // verbose stats
+};
+
+// SAT solving manager
+typedef struct Cec2_Man_t_ Cec2_Man_t;
+struct Cec2_Man_t_
+{
+ Cec2_Par_t * pPars; // parameters
+ Gia_Man_t * pAig; // user's AIG
+ Gia_Man_t * pNew; // internal AIG
+ // SAT solving
+ satoko_t * pSat; // SAT solver
+ Vec_Ptr_t * vFrontier; // CNF construction
+ Vec_Ptr_t * vFanins; // CNF construction
+ Vec_Wrd_t * vSims; // CI simulation info
+ Vec_Int_t * vNodesNew; // nodes
+ Vec_Int_t * vSatVars; // nodes
+ Vec_Int_t * vObjSatPairs; // nodes
+ Vec_Int_t * vCexTriples; // nodes
+ // statistics
+ int nSatSat;
+ int nSatUnsat;
+ int nSatUndec;
+ abctime timeSatSat;
+ abctime timeSatUnsat;
+ abctime timeSatUndec;
+ abctime timeSim;
+ abctime timeRefine;
+ abctime timeExtra;
+ abctime timeStart;
+};
+
+static inline int Cec2_ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjCopyArray(p, Gia_ObjId(p, pObj)); }
+static inline int Cec2_ObjSetSatId( Gia_Man_t * p, Gia_Obj_t * pObj, int Num ) { assert(Cec2_ObjSatId(p, pObj) == -1); Gia_ObjSetCopyArray(p, Gia_ObjId(p, pObj), Num); return Num; }
+static inline void Cec2_ObjCleanSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(Cec2_ObjSatId(p, pObj) != -1); Gia_ObjSetCopyArray(p, Gia_ObjId(p, pObj), -1); }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Sets parameter defaults.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec2_SetDefaultParams( Cec2_Par_t * p )
+{
+ memset( p, 0, sizeof(Cec2_Par_t) );
+ p->nSimWords = 8; // simulation words
+ p->nSimRounds = 4; // simulation rounds
+ p->nConfLimit = 1000; // conflict limit at a node
+ p->fIsMiter = 0; // this is a miter
+ p->fUseCones = 1; // use logic cones
+ p->fVeryVerbose = 0; // verbose stats
+ p->fVerbose = 1; // verbose stats
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses to the solver.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec2_AddClausesMux( Gia_Man_t * p, Gia_Obj_t * pNode, satoko_t * pSat )
+{
+ int fPolarFlip = 0;
+ Gia_Obj_t * pNodeI, * pNodeT, * pNodeE;
+ int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE;
+
+ assert( !Gia_IsComplement( pNode ) );
+ assert( pNode->fMark0 );
+ // get nodes (I = if, T = then, E = else)
+ pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE );
+ // get the variable numbers
+ VarF = Cec2_ObjSatId(p, pNode);
+ VarI = Cec2_ObjSatId(p, pNodeI);
+ VarT = Cec2_ObjSatId(p, Gia_Regular(pNodeT));
+ VarE = Cec2_ObjSatId(p, Gia_Regular(pNodeE));
+ // get the complementation flags
+ fCompT = Gia_IsComplement(pNodeT);
+ fCompE = Gia_IsComplement(pNodeE);
+
+ // f = ITE(i, t, e)
+
+ // i' + t' + f
+ // i' + t + f'
+ // i + e' + f
+ // i + e + f'
+
+ // create four clauses
+ pLits[0] = Abc_Var2Lit(VarI, 1);
+ pLits[1] = Abc_Var2Lit(VarT, 1^fCompT);
+ pLits[2] = Abc_Var2Lit(VarF, 0);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarI, 1);
+ pLits[1] = Abc_Var2Lit(VarT, 0^fCompT);
+ pLits[2] = Abc_Var2Lit(VarF, 1);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarI, 0);
+ pLits[1] = Abc_Var2Lit(VarE, 1^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 0);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarI, 0);
+ pLits[1] = Abc_Var2Lit(VarE, 0^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 1);
+ if ( fPolarFlip )
+ {
+ if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, 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] = Abc_Var2Lit(VarT, 0^fCompT);
+ pLits[1] = Abc_Var2Lit(VarE, 0^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 1);
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+ pLits[0] = Abc_Var2Lit(VarT, 1^fCompT);
+ pLits[1] = Abc_Var2Lit(VarE, 1^fCompE);
+ pLits[2] = Abc_Var2Lit(VarF, 0);
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 3 );
+ assert( RetValue );
+}
+void Cec2_AddClausesSuper( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper, satoko_t * pSat )
+{
+ int fPolarFlip = 0;
+ Gia_Obj_t * pFanin;
+ int * pLits, nLits, RetValue, i;
+ assert( !Gia_IsComplement(pNode) );
+ assert( Gia_ObjIsAnd( pNode ) );
+ // create storage for literals
+ nLits = Vec_PtrSize(vSuper) + 1;
+ pLits = ABC_ALLOC( int, nLits );
+ // suppose AND-gate is A & B = C
+ // add !A => !C or A + !C
+ Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i )
+ {
+ pLits[0] = Abc_Var2Lit(Cec2_ObjSatId(p, Gia_Regular(pFanin)), Gia_IsComplement(pFanin));
+ pLits[1] = Abc_Var2Lit(Cec2_ObjSatId(p, pNode), 1);
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pFanin)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] );
+ if ( pNode->fPhase ) pLits[1] = Abc_LitNot( pLits[1] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, 2 );
+ assert( RetValue );
+ }
+ // add A & B => C or !A + !B + C
+ Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i )
+ {
+ pLits[i] = Abc_Var2Lit(Cec2_ObjSatId(p, Gia_Regular(pFanin)), !Gia_IsComplement(pFanin));
+ if ( fPolarFlip )
+ {
+ if ( Gia_Regular(pFanin)->fPhase ) pLits[i] = Abc_LitNot( pLits[i] );
+ }
+ }
+ pLits[nLits-1] = Abc_Var2Lit(Cec2_ObjSatId(p, pNode), 0);
+ if ( fPolarFlip )
+ {
+ if ( pNode->fPhase ) pLits[nLits-1] = Abc_LitNot( pLits[nLits-1] );
+ }
+ RetValue = satoko_add_clause( pSat, pLits, nLits );
+ assert( RetValue );
+ ABC_FREE( pLits );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds clauses and returns CNF variable of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec2_CollectSuper_rec( Gia_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes )
+{
+ // if the new node is complemented or a PI, another gate begins
+ if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) ||
+ (!fFirst && Gia_ObjValue(pObj) > 1) ||
+ (fUseMuxes && pObj->fMark0) )
+ {
+ Vec_PtrPushUnique( vSuper, pObj );
+ return;
+ }
+ // go through the branches
+ Cec2_CollectSuper_rec( Gia_ObjChild0(pObj), vSuper, 0, fUseMuxes );
+ Cec2_CollectSuper_rec( Gia_ObjChild1(pObj), vSuper, 0, fUseMuxes );
+}
+void Cec2_CollectSuper( Gia_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper )
+{
+ assert( !Gia_IsComplement(pObj) );
+ assert( !Gia_ObjIsCi(pObj) );
+ Vec_PtrClear( vSuper );
+ Cec2_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes );
+}
+void Cec2_ObjAddToFrontier( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vFrontier, satoko_t * pSat )
+{
+ assert( !Gia_IsComplement(pObj) );
+ assert( !Gia_ObjIsConst0(pObj) );
+ if ( Cec2_ObjSatId(p, pObj) >= 0 )
+ return;
+ assert( Cec2_ObjSatId(p, pObj) == -1 );
+ Cec2_ObjSetSatId( p, pObj, satoko_add_variable(pSat, 0) );
+ if ( Gia_ObjIsAnd(pObj) )
+ Vec_PtrPush( vFrontier, pObj );
+}
+int Cec2_ObjGetCnfVar( Cec2_Man_t * p, int iObj )
+{
+ Gia_Obj_t * pNode, * pFanin;
+ Gia_Obj_t * pObj = Gia_ManObj(p->pNew, iObj);
+ int i, k, fUseMuxes = 1;
+ // quit if CNF is ready
+ if ( Cec2_ObjSatId(p->pNew,pObj) >= 0 )
+ return Cec2_ObjSatId(p->pNew,pObj);
+ assert( iObj > 0 );
+ if ( Gia_ObjIsCi(pObj) )
+ return Cec2_ObjSetSatId( p->pNew, pObj, satoko_add_variable(p->pSat, 0) );
+ assert( Gia_ObjIsAnd(pObj) );
+ // start the frontier
+ Vec_PtrClear( p->vFrontier );
+ Cec2_ObjAddToFrontier( p->pNew, pObj, p->vFrontier, p->pSat );
+ // explore nodes in the frontier
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFrontier, pNode, i )
+ {
+ // create the supergate
+ assert( Cec2_ObjSatId(p->pNew,pNode) >= 0 );
+ if ( fUseMuxes && pNode->fMark0 )
+ {
+ Vec_PtrClear( p->vFanins );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin1(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin0(pNode) ) );
+ Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin1(pNode) ) );
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k )
+ Cec2_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat );
+ Cec2_AddClausesMux( p->pNew, pNode, p->pSat );
+ }
+ else
+ {
+ Cec2_CollectSuper( pNode, fUseMuxes, p->vFanins );
+ Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k )
+ Cec2_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat );
+ Cec2_AddClausesSuper( p->pNew, pNode, p->vFanins, p->pSat );
+ }
+ assert( Vec_PtrSize(p->vFanins) > 1 );
+ }
+ return Cec2_ObjSatId(p->pNew,pObj);
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Internal simulation APIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline word * Cec2_ObjSim( Gia_Man_t * p, int iObj )
+{
+ return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj );
+}
+static inline void Cec2_ObjSimSetInputBit( Gia_Man_t * p, int iObj, int Bit )
+{
+ word * pSim = Cec2_ObjSim( p, iObj );
+ if ( Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi ) != Bit )
+ Abc_InfoXorBit( (unsigned*)pSim, p->iPatsPi );
+}
+static inline void Cec2_ObjSimRo( Gia_Man_t * p, int iObj )
+{
+ int w;
+ word * pSimRo = Cec2_ObjSim( p, iObj );
+ word * pSimRi = Cec2_ObjSim( p, Gia_ObjRoToRiId(p, iObj) );
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSimRo[w] = pSimRi[w];
+}
+static inline void Cec2_ObjSimCo( Gia_Man_t * p, int iObj )
+{
+ int w;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ word * pSimCo = Cec2_ObjSim( p, iObj );
+ word * pSimDri = Cec2_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
+ if ( Gia_ObjFaninC0(pObj) )
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSimCo[w] = ~pSimDri[w];
+ else
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSimCo[w] = pSimDri[w];
+}
+static inline void Cec2_ObjSimAnd( Gia_Man_t * p, int iObj )
+{
+ int w;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ word * pSim = Cec2_ObjSim( p, iObj );
+ word * pSim0 = Cec2_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );
+ word * pSim1 = Cec2_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) );
+ if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = ~pSim0[w] & ~pSim1[w];
+ else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) )
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = ~pSim0[w] & pSim1[w];
+ else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = pSim0[w] & ~pSim1[w];
+ else
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = pSim0[w] & pSim1[w];
+}
+static inline int Cec2_ObjSimEqual( Gia_Man_t * p, int iObj0, int iObj1 )
+{
+ int w;
+ word * pSim0 = Cec2_ObjSim( p, iObj0 );
+ word * pSim1 = Cec2_ObjSim( p, iObj1 );
+ if ( (pSim0[0] & 1) == (pSim1[0] & 1) )
+ {
+ for ( w = 0; w < p->nSimWords; w++ )
+ if ( pSim0[w] != pSim1[w] )
+ return 0;
+ return 1;
+ }
+ else
+ {
+ for ( w = 0; w < p->nSimWords; w++ )
+ if ( pSim0[w] != ~pSim1[w] )
+ return 0;
+ return 1;
+ }
+}
+static inline void Cec2_ObjSimCi( Gia_Man_t * p, int iObj )
+{
+ int w;
+ word * pSim = Cec2_ObjSim( p, iObj );
+ for ( w = 0; w < p->nSimWords; w++ )
+ pSim[w] = Gia_ManRandomW( 0 );
+ pSim[0] <<= 1;
+}
+void Cec2_ManSimulateCis( Gia_Man_t * p )
+{
+ int i, Id;
+ Gia_ManForEachCiId( p, Id, i )
+ Cec2_ObjSimCi( p, Id );
+ p->iPatsPi = 1;
+}
+Abc_Cex_t * Cec2_ManDeriveCex( Gia_Man_t * p, int iOut, int iPat )
+{
+ Abc_Cex_t * pCex;
+ int i, Id;
+ pCex = Abc_CexAlloc( 0, Gia_ManCiNum(p), 1 );
+ pCex->iPo = iOut;
+ if ( iPat == -1 )
+ return pCex;
+ Gia_ManForEachCiId( p, Id, i )
+ if ( Abc_InfoHasBit((unsigned *)Cec2_ObjSim(p, Id), iPat) )
+ Abc_InfoSetBit( pCex->pData, i );
+ return pCex;
+}
+int Cec2_ManSimulateCos( Gia_Man_t * p )
+{
+ int i, Id;
+ // check outputs and generate CEX if they fail
+ Gia_ManForEachCoId( p, Id, i )
+ {
+ Cec2_ObjSimCo( p, Id );
+ if ( Cec2_ObjSimEqual(p, Id, 0) )
+ continue;
+ p->pCexSeq = Cec2_ManDeriveCex( p, i, Abc_TtFindFirstBit2(Cec2_ObjSim(p, Id), p->nSimWords) );
+ return 0;
+ }
+ return 1;
+}
+void Cec2_ManSaveCis( Gia_Man_t * p )
+{
+ int w, i, Id;
+ assert( p->vSimsPi != NULL );
+ for ( w = 0; w < p->nSimWords; w++ )
+ Gia_ManForEachCiId( p, Id, i )
+ Vec_WrdPush( p->vSimsPi, Cec2_ObjSim(p, Id)[w] );
+}
+void Cec2_ManSimulate( Gia_Man_t * p, Vec_Int_t * vTriples, Cec2_Man_t * pMan )
+{
+ extern void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr );
+ abctime clk = Abc_Clock();
+ Gia_Obj_t * pObj;
+ int i, iRepr, iObj, Entry;
+ //Cec2_ManSaveCis( p );
+ Gia_ManForEachAnd( p, pObj, i )
+ Cec2_ObjSimAnd( p, i );
+ pMan->timeSim += Abc_Clock() - clk;
+ if ( p->pReprs == NULL )
+ return;
+ if ( vTriples )
+ {
+ Vec_IntForEachEntryTriple( vTriples, iRepr, iObj, Entry, i )
+ {
+ word * pSim0 = Cec2_ObjSim( p, iRepr );
+ word * pSim1 = Cec2_ObjSim( p, iObj );
+ int iPat = Abc_Lit2Var(Entry);
+ int fPhase = Abc_LitIsCompl(Entry);
+ if ( (fPhase ^ Abc_InfoHasBit((unsigned *)pSim0, iPat)) == Abc_InfoHasBit((unsigned *)pSim1, iPat) )
+ printf( "ERROR: Pattern %d did not disprove pair %d and %d.\n", iPat, iRepr, iObj );
+ }
+ }
+ clk = Abc_Clock();
+ Gia_ManForEachClass0( p, i )
+ Cec2_ManSimClassRefineOne( p, i );
+ pMan->timeRefine += Abc_Clock() - clk;
+}
+void Cec2_ManSimAlloc( Gia_Man_t * p, int nWords )
+{
+ Vec_WrdFreeP( &p->vSims );
+ Vec_WrdFreeP( &p->vSimsPi );
+ p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords );
+ p->vSimsPi = Vec_WrdAlloc( Gia_ManCiNum(p) * nWords * 4 ); // storage for CI patterns
+ p->nSimWords = nWords;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Computes hash key of the simulation info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec2_ManSimHashKey( word * pSim, int nSims, int nTableSize )
+{
+ static int s_Primes[16] = {
+ 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177,
+ 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 };
+ unsigned uHash = 0, * pSimU = (unsigned *)pSim;
+ int i, nSimsU = 2 * nSims;
+ if ( pSimU[0] & 1 )
+ for ( i = 0; i < nSimsU; i++ )
+ uHash ^= ~pSimU[i] * s_Primes[i & 0xf];
+ else
+ for ( i = 0; i < nSimsU; i++ )
+ uHash ^= pSimU[i] * s_Primes[i & 0xf];
+ return (int)(uHash % nTableSize);
+
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creating initial equivalence classes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr )
+{
+ int iObj, iPrev = iRepr, iPrev2, iRepr2;
+ Gia_ClassForEachObj1( p, iRepr, iRepr2 )
+ if ( Cec2_ObjSimEqual(p, iRepr, iRepr2) )
+ iPrev = iRepr2;
+ else
+ break;
+ if ( iRepr2 <= 0 ) // no refinement
+ return;
+ // relink remaining nodes of the class
+ // nodes that are equal to iRepr, remain in the class of iRepr
+ // nodes that are not equal to iRepr, move to the class of iRepr2
+ Gia_ObjSetRepr( p, iRepr2, GIA_VOID );
+ iPrev2 = iRepr2;
+ for ( iObj = Gia_ObjNext(p, iRepr2); iObj > 0; iObj = Gia_ObjNext(p, iObj) )
+ {
+ if ( Cec2_ObjSimEqual(p, iRepr, iObj) ) // remains with iRepr
+ {
+ Gia_ObjSetNext( p, iPrev, iObj );
+ iPrev = iObj;
+ }
+ else // moves to iRepr2
+ {
+ Gia_ObjSetRepr( p, iObj, iRepr2 );
+ Gia_ObjSetNext( p, iPrev2, iObj );
+ iPrev2 = iObj;
+ }
+ }
+ Gia_ObjSetNext( p, iPrev, -1 );
+ Gia_ObjSetNext( p, iPrev2, -1 );
+}
+void Cec2_ManCreateClasses( Gia_Man_t * p, Cec2_Man_t * pMan )
+{
+ abctime clk;
+ Gia_Obj_t * pObj;
+ int nWords = p->nSimWords;
+ int * pTable, nTableSize, i, Key;
+ // allocate representation
+ ABC_FREE( p->pReprs );
+ ABC_FREE( p->pNexts );
+ p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) );
+ p->pNexts = ABC_FALLOC( int, Gia_ManObjNum(p) );
+ // hash each node by its simulation info
+ nTableSize = Abc_PrimeCudd( Gia_ManObjNum(p) );
+ pTable = ABC_FALLOC( int, nTableSize );
+ Gia_ManForEachObj( p, pObj, i )
+ {
+ p->pReprs[i].iRepr = GIA_VOID;
+ if ( Gia_ObjIsCo(pObj) )
+ continue;
+ Key = Cec2_ManSimHashKey( Cec2_ObjSim(p, i), nWords, nTableSize );
+ assert( Key >= 0 && Key < nTableSize );
+ if ( pTable[Key] == -1 )
+ pTable[Key] = i;
+ else
+ Gia_ObjSetRepr( p, i, pTable[Key] );
+ }
+ // create classes
+ for ( i = Gia_ManObjNum(p) - 1; i >= 0; i-- )
+ {
+ int iRepr = Gia_ObjRepr(p, i);
+ if ( iRepr == GIA_VOID )
+ continue;
+ Gia_ObjSetNext( p, i, Gia_ObjNext(p, iRepr) );
+ Gia_ObjSetNext( p, iRepr, i );
+ }
+ ABC_FREE( pTable );
+ clk = Abc_Clock();
+ Gia_ManForEachClass0( p, i )
+ Cec2_ManSimClassRefineOne( p, i );
+ pMan->timeRefine += Abc_Clock() - clk;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars )
+{
+ Cec2_Man_t * p;
+ Gia_Obj_t * pObj; int i;
+ //assert( Gia_ManRegNum(pAig) == 0 );
+ p = ABC_CALLOC( Cec2_Man_t, 1 );
+ memset( p, 0, sizeof(Cec2_Man_t) );
+ p->timeStart = Abc_Clock();
+ p->pPars = pPars;
+ p->pAig = pAig;
+ // create new manager
+ p->pNew = Gia_ManStart( Gia_ManObjNum(pAig) );
+ Gia_ManFillValue( pAig );
+ Gia_ManConst0(pAig)->Value = 0;
+ Gia_ManForEachCi( pAig, pObj, i )
+ pObj->Value = Gia_ManAppendCi( p->pNew );
+ Gia_ManHashAlloc( p->pNew );
+ Vec_IntFill( &p->pNew->vCopies, Gia_ManObjNum(p->pNew), -1 );
+ // SAT solving
+ p->pSat = satoko_create();
+ p->vFrontier = Vec_PtrAlloc( 1000 );
+ p->vFanins = Vec_PtrAlloc( 100 );
+ p->vNodesNew = Vec_IntAlloc( 100 );
+ p->vSatVars = Vec_IntAlloc( 100 );
+ p->vObjSatPairs = Vec_IntAlloc( 100 );
+ p->vCexTriples = Vec_IntAlloc( 100 );
+ // remember pointer to the solver in the AIG manager
+ pAig->pData = p->pSat;
+ return p;
+}
+void Cec2_ManDestroy( Cec2_Man_t * p )
+{
+ if ( p->pPars->fVerbose )
+ {
+ abctime timeTotal = Abc_Clock() - p->timeStart;
+ abctime timeSat = p->timeSatSat + p->timeSatUnsat + p->timeSatUndec;
+ abctime timeOther = timeTotal - timeSat - p->timeSim - p->timeRefine - p->timeExtra;
+// Abc_Print( 1, "%d\n", p->Num );
+ ABC_PRTP( "SAT solving", timeSat, timeTotal );
+ ABC_PRTP( " sat ", p->timeSatSat, timeTotal );
+ ABC_PRTP( " unsat ", p->timeSatUnsat, timeTotal );
+ ABC_PRTP( " fail ", p->timeSatUndec, timeTotal );
+ ABC_PRTP( "Simulation ", p->timeSim, timeTotal );
+ ABC_PRTP( "Refinement ", p->timeRefine, timeTotal );
+ ABC_PRTP( "Rollback ", p->timeExtra, timeTotal );
+ ABC_PRTP( "Other ", timeOther, timeTotal );
+ ABC_PRTP( "TOTAL ", timeTotal, timeTotal );
+ fflush( stdout );
+ }
+
+ Vec_WrdFreeP( &p->pAig->vSims );
+ //Vec_WrdFreeP( &p->pAig->vSimsPi );
+ Gia_ManCleanMark01( p->pAig );
+ satoko_destroy( p->pSat );
+ Gia_ManStopP( &p->pNew );
+ Vec_PtrFreeP( &p->vFrontier );
+ Vec_PtrFreeP( &p->vFanins );
+ Vec_IntFreeP( &p->vNodesNew );
+ Vec_IntFreeP( &p->vSatVars );
+ Vec_IntFreeP( &p->vObjSatPairs );
+ Vec_IntFreeP( &p->vCexTriples );
+ ABC_FREE( p );
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Verify counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec2_ManVerify_rec( Gia_Man_t * p, int iObj, satoko_t * pSat )
+{
+ int Value0, Value1;
+ Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
+ if ( iObj == 0 ) return 0;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return pObj->fMark1;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ if ( Gia_ObjIsCi(pObj) )
+ return pObj->fMark1 = var_polarity(pSat, Cec2_ObjSatId(p, pObj)) == LIT_TRUE;
+ assert( Gia_ObjIsAnd(pObj) );
+ Value0 = Cec2_ManVerify_rec( p, Gia_ObjFaninId0(pObj, iObj), pSat ) ^ Gia_ObjFaninC0(pObj);
+ Value1 = Cec2_ManVerify_rec( p, Gia_ObjFaninId1(pObj, iObj), pSat ) ^ Gia_ObjFaninC1(pObj);
+ return pObj->fMark1 = Value0 & Value1;
+}
+void Cec2_ManVerify( Gia_Man_t * p, int iObj0, int iObj1, int fPhase, satoko_t * pSat )
+{
+// int val0 = var_polarity(pSat, Cec2_ObjSatId(p, Gia_ManObj(p, iObj0))) == LIT_TRUE;
+// int val1 = var_polarity(pSat, Cec2_ObjSatId(p, Gia_ManObj(p, iObj1))) == LIT_TRUE;
+ int Value0, Value1;
+ Gia_ManIncrementTravId( p );
+ Value0 = Cec2_ManVerify_rec( p, iObj0, pSat );
+ Value1 = Cec2_ManVerify_rec( p, iObj1, pSat );
+ if ( (Value0 ^ Value1) == fPhase )
+ printf( "CEX verification FAILED for obj %d and obj %d.\n", iObj0, iObj1 );
+// else
+// printf( "CEX verification succeeded for obj %d and obj %d.\n", iObj0, iObj1 );;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Internal simulation APIs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Cec2_ManCollect_rec( Cec2_Man_t * p, int iObj )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjIsTravIdCurrentId(p->pNew, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p->pNew, iObj);
+ pObj = Gia_ManObj( p->pNew, iObj );
+ if ( Cec2_ObjSatId(p->pNew, pObj) >= 0 )
+ {
+ Vec_IntPush( p->vNodesNew, iObj );
+ Vec_IntPush( p->vSatVars, Cec2_ObjSatId(p->pNew, pObj) );
+ }
+ if ( !iObj )
+ return;
+ if ( Gia_ObjIsAnd(pObj) )
+ {
+ Cec2_ManCollect_rec( p, Gia_ObjFaninId0(pObj, iObj) );
+ Cec2_ManCollect_rec( p, Gia_ObjFaninId1(pObj, iObj) );
+ }
+ else
+ {
+ assert( Cec2_ObjSatId(p->pNew, pObj) >= 0 );
+ Vec_IntPushTwo( p->vObjSatPairs, Gia_ManCiIdToId(p->pAig, Gia_ObjCioId(pObj)), Cec2_ObjSatId(p->pNew, pObj) ); // SAT var
+ }
+}
+int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase )
+{
+ Gia_Obj_t * pObj;
+ int status, i, iVar0, iVar1;
+ if (iObj1 < iObj0)
+ iObj1 ^= iObj0, iObj0 ^= iObj1, iObj1 ^= iObj0;
+ assert( iObj0 < iObj1 );
+ assert( p->pPars->fUseCones || solver_varnum(p->pSat) == 0 );
+ if ( !iObj0 && Cec2_ObjSatId(p->pNew, Gia_ManConst0(p->pNew)) == -1 )
+ Cec2_ObjSetSatId( p->pNew, Gia_ManConst0(p->pNew), satoko_add_variable(p->pSat, 0) );
+ iVar0 = Cec2_ObjGetCnfVar( p, iObj0 );
+ iVar1 = Cec2_ObjGetCnfVar( p, iObj1 );
+ // collect inputs and internal nodes
+ Vec_IntClear( p->vNodesNew );
+ Vec_IntClear( p->vSatVars );
+ Vec_IntClear( p->vObjSatPairs );
+ Gia_ManIncrementTravId( p->pNew );
+ Cec2_ManCollect_rec( p, iObj0 );
+ Cec2_ManCollect_rec( p, iObj1 );
+//printf( "%d ", Vec_IntSize(p->vNodesNew) );
+ // solve direct
+ if ( p->pPars->fUseCones ) satoko_mark_cone( p->pSat, Vec_IntArray(p->vSatVars), Vec_IntSize(p->vSatVars) );
+ satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 1) );
+ satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, fPhase) );
+ status = satoko_solve( p->pSat );
+ satoko_assump_pop( p->pSat );
+ satoko_assump_pop( p->pSat );
+ if ( status == SATOKO_UNSAT && iObj0 > 0 )
+ {
+ // solve reverse
+ satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 0) );
+ satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, !fPhase) );
+ status = satoko_solve( p->pSat );
+ satoko_assump_pop( p->pSat );
+ satoko_assump_pop( p->pSat );
+ }
+ if ( p->pPars->fUseCones ) satoko_unmark_cone( p->pSat, Vec_IntArray(p->vSatVars), Vec_IntSize(p->vSatVars) );
+ //if ( status == SATOKO_SAT )
+ // Cec2_ManVerify( p->pNew, iObj0, iObj1, fPhase, p->pSat );
+ if ( p->pPars->fUseCones )
+ return status;
+ Gia_ManForEachObjVec( p->vNodesNew, p->pNew, pObj, i )
+ Cec2_ObjCleanSatId( p->pNew, pObj );
+ return status;
+}
+
+int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj )
+{
+ abctime clk = Abc_Clock();
+ int i, IdAig, IdSat, status, RetValue = 1;
+ Gia_Obj_t * pObj = Gia_ManObj( p->pAig, iObj );
+ Gia_Obj_t * pRepr = Gia_ObjReprObj( p->pAig, iObj );
+ int fCompl = Abc_LitIsCompl(pObj->Value) ^ Abc_LitIsCompl(pRepr->Value) ^ pObj->fPhase ^ pRepr->fPhase;
+ status = Cec2_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl );
+ if ( status == SATOKO_SAT )
+ {
+ p->nSatSat++;
+ p->pAig->iPatsPi = (p->pAig->iPatsPi == 64 * p->pAig->nSimWords - 1) ? 1 : p->pAig->iPatsPi + 1;
+ assert( p->pAig->iPatsPi > 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords );
+ Vec_IntForEachEntryDouble( p->vObjSatPairs, IdAig, IdSat, i )
+ Cec2_ObjSimSetInputBit( p->pAig, IdAig, var_polarity(p->pSat, IdSat) == LIT_TRUE );
+ RetValue = 0;
+ p->timeSatSat += Abc_Clock() - clk;
+ }
+ else if ( status == SATOKO_UNSAT )
+ {
+ p->nSatUnsat++;
+ pObj->Value = Abc_LitNotCond( pRepr->Value, fCompl );
+ Gia_ObjSetProved( p->pAig, iObj );
+ p->timeSatUnsat += Abc_Clock() - clk;
+ }
+ else
+ {
+ p->nSatUndec++;
+ assert( status == SATOKO_UNDEC );
+ Gia_ObjSetFailed( p->pAig, iObj );
+ assert( 0 );
+ p->timeSatUndec += Abc_Clock() - clk;
+ }
+ if ( p->pPars->fUseCones )
+ return RetValue;
+ clk = Abc_Clock();
+ satoko_rollback( p->pSat );
+ p->timeExtra += Abc_Clock() - clk;
+ p->pSat->stats.n_conflicts = 0;
+ return RetValue;
+}
+void Cec2_ManPrintStats( Gia_Man_t * p, Cec2_Par_t * pPars, Cec2_Man_t * pMan )
+{
+ if ( !pPars->fVerbose )
+ return;
+ printf( "S =%5d ", pMan ? pMan->nSatSat : 0 );
+ printf( "U =%5d ", pMan ? pMan->nSatUnsat : 0 );
+ printf( "F =%5d ", pMan ? pMan->nSatUndec : 0 );
+ Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 );
+}
+int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars )
+{
+ Cec2_Man_t * pMan = Cec2_ManCreate( p, pPars );
+ Gia_Obj_t * pObj, * pRepr, * pObjNew;
+ int i, Iter, fDisproved = 1;
+
+ // check if any output trivially fails under all-0 pattern
+ Gia_ManSetPhase( p );
+ if ( pPars->fIsMiter )
+ {
+ Gia_ManForEachCo( p, pObj, i )
+ if ( pObj->fPhase )
+ {
+ p->pCexSeq = Cec2_ManDeriveCex( p, i, -1 );
+ return 0;
+ }
+ }
+
+ // simulate one round and create classes
+ Cec2_ManSimAlloc( p, pPars->nSimWords );
+ Cec2_ManSimulateCis( p );
+ Cec2_ManSimulate( p, NULL, pMan );
+ if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected
+ return 0;
+ Cec2_ManCreateClasses( p, pMan );
+ Cec2_ManPrintStats( p, pPars, pMan );
+
+ // perform additinal simulation
+ for ( i = 0; i < pPars->nSimRounds; i++ )
+ {
+ Cec2_ManSimulateCis( p );
+ Cec2_ManSimulate( p, NULL, pMan );
+ if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected
+ return 0;
+ Cec2_ManPrintStats( p, pPars, pMan );
+ }
+ // perform sweeping
+ //pMan = Cec2_ManCreate( p, pPars );
+ for ( Iter = 0; fDisproved; Iter++ )
+ {
+ fDisproved = 0;
+ Cec2_ManSimulateCis( p );
+ Vec_IntClear( pMan->vCexTriples );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 || Gia_ObjFanin1(pObj)->fMark1;
+ if ( pObj->fMark1 ) // skip nodes in the TFO of a disproved one
+ continue;
+ if ( ~pObj->Value ) // skip swept nodes
+ continue;
+ if ( !~Gia_ObjFanin0(pObj)->Value || !~Gia_ObjFanin1(pObj)->Value ) // skip fanouts of non-swept nodes
+ continue;
+ assert( !Gia_ObjProved(p, i) && !Gia_ObjFailed(p, i) );
+ // duplicate the node
+ pObj->Value = Gia_ManHashAnd( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ if ( Vec_IntSize(&pMan->pNew->vCopies) == Abc_Lit2Var(pObj->Value) )
+ {
+ pObjNew = Gia_ManObj( pMan->pNew, Abc_Lit2Var(pObj->Value) );
+ pObjNew->fMark0 = Gia_ObjIsMuxType( pObjNew );
+ Gia_ObjSetPhase( pMan->pNew, pObjNew );
+ Vec_IntPush( &pMan->pNew->vCopies, -1 );
+ }
+ assert( Vec_IntSize(&pMan->pNew->vCopies) == Gia_ManObjNum(pMan->pNew) );
+ pRepr = Gia_ObjReprObj( p, i );
+ if ( pRepr == NULL || pRepr->fMark1 || !~pRepr->Value )
+ continue;
+ if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) )
+ {
+ assert( (pObj->Value ^ pRepr->Value) == (pObj->fPhase ^ pRepr->fPhase) );
+ Gia_ObjSetProved( p, i );
+ continue;
+ }
+ if ( Cec2_ManSweepNode(pMan, i) )
+ continue;
+ pObj->Value = ~0;
+ //Vec_IntPushThree( pMan->vCexTriples, Gia_ObjId(p, pRepr), i, Abc_Var2Lit(p->iPatsPi, pObj->fPhase ^ pRepr->fPhase) );
+ // mark nodes as disproved
+ fDisproved = 1;
+ //if ( Iter > 5 )
+ continue;
+ if ( Gia_ObjIsAnd(pRepr) )
+ pRepr->fMark1 = 1;
+ pObj->fMark1 = 1;
+ }
+ if ( fDisproved )
+ {
+ //printf( "The number of pattern = %d.\n", p->iPatsPi );
+ Cec2_ManSimulate( p, pMan->vCexTriples, pMan );
+ if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected
+ break;
+ }
+ Cec2_ManPrintStats( p, pPars, pMan );
+ }
+ Cec2_ManDestroy( pMan );
+ //Gia_ManEquivPrintClasses( p, 1, 0 );
+ return p->pCexSeq ? 0 : 1;
+}
+void Cec2_ManSimulateTest( Gia_Man_t * p )
+{
+ //abctime clk = Abc_Clock();
+ Cec2_Par_t Pars, * pPars = &Pars;
+ Cec2_SetDefaultParams( pPars );
+// Gia_ManComputeGiaEquivs( p, 100000, 0 );
+// Gia_ManEquivPrintClasses( p, 1, 0 );
+ Cec2_ManPerformSweeping( p, pPars );
+ //Abc_PrintTime( 1, "SAT sweeping time", Abc_Clock() - clk );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/cecSimBack.c b/src/proof/cec/cecSimBack.c
new file mode 100644
index 00000000..c3d09ff5
--- /dev/null
+++ b/src/proof/cec/cecSimBack.c
@@ -0,0 +1,194 @@
+/**CFile****************************************************************
+
+ FileName [cecSimBack.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Combinational equivalence checking.]
+
+ Synopsis [Backward simulation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: cecSimBack.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "cecInt.h"
+#include "aig/gia/giaAig.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ObjSatVerify( Gia_Man_t * p, Gia_Obj_t * pRoot, int Value )
+{
+ Gia_Obj_t * pObj;
+ int i, RetValue = 1;
+ printf( "Obj = %4d Value = %d ", Gia_ObjId(p, pRoot), Value );
+ Gia_ObjTerSimSet0( Gia_ManConst0(p) );
+ Gia_ManForEachCi( p, pObj, i )
+ if ( !Gia_ObjIsTravIdCurrent(p, pObj) )
+ Gia_ObjTerSimSetX( pObj ), printf( "x" );
+ else if ( pObj->fMark0 )
+ Gia_ObjTerSimSet1( pObj ), printf( "1" );
+ else
+ Gia_ObjTerSimSet0( pObj ), printf( "0" );
+ printf( " " );
+ Gia_ManForEachAnd( p, pObj, i )
+ Gia_ObjTerSimAnd( pObj );
+ if ( Value ? Gia_ObjTerSimGet1(pRoot) : Gia_ObjTerSimGet0(pRoot) )
+ printf( "Verification successful.\n" );
+ else
+ printf( "Verification failed.\n" ), RetValue = 0;
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Return 1 if pObj can have Value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+word Cec_ManCheckSat2_rec( Gia_Man_t * p, Gia_Obj_t * pObj, word Value, Vec_Wrd_t * vValues )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return Value == (int)pObj->fMark0;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ pObj->fMark0 = Value;
+ if ( !Gia_ObjIsAnd(pObj) )
+ return 1;
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( Value )
+ {
+ return Cec_ManCheckSat2_rec( p, pFan0, !Gia_ObjFaninC0(pObj), vValues ) &&
+ Cec_ManCheckSat2_rec( p, pFan1, !Gia_ObjFaninC1(pObj), vValues );
+ }
+ if ( Gia_ObjIsTravIdCurrent(p, pFan0) ) // already assigned
+ {
+ if ( Gia_ObjFaninC0(pObj) == (int)pFan0->fMark0 ) // justified
+ return 1;
+ return Cec_ManCheckSat2_rec( p, pFan1, Gia_ObjFaninC1(pObj), vValues );
+ }
+ if ( Gia_ObjIsTravIdCurrent(p, pFan1) ) // already assigned
+ {
+ if ( Gia_ObjFaninC1(pObj) == (int)pFan1->fMark0 ) // justified
+ return 1;
+ return Cec_ManCheckSat2_rec( p, pFan0, Gia_ObjFaninC0(pObj), vValues );
+ }
+ return Cec_ManCheckSat2_rec( p, pFan0, Gia_ObjFaninC0(pObj), vValues );
+}
+word Cec_ManCheckSat2( Gia_Man_t * p, Gia_Obj_t * pObj, int Value, Vec_Wrd_t * vValues )
+{
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Return 1 if pObj can have Value.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Cec_ManCheckSat_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int Value )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ if ( Gia_ObjIsTravIdCurrent(p, pObj) )
+ return Value == (int)pObj->fMark0;
+ Gia_ObjSetTravIdCurrent(p, pObj);
+ pObj->fMark0 = Value;
+ if ( !Gia_ObjIsAnd(pObj) )
+ return 1;
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( Value )
+ {
+ return Cec_ManCheckSat_rec( p, pFan0, !Gia_ObjFaninC0(pObj) ) &&
+ Cec_ManCheckSat_rec( p, pFan1, !Gia_ObjFaninC1(pObj) );
+ }
+ if ( Gia_ObjIsTravIdCurrent(p, pFan0) ) // already assigned
+ {
+ if ( Gia_ObjFaninC0(pObj) == (int)pFan0->fMark0 ) // justified
+ return 1;
+ return Cec_ManCheckSat_rec( p, pFan1, Gia_ObjFaninC1(pObj) );
+ }
+ if ( Gia_ObjIsTravIdCurrent(p, pFan1) ) // already assigned
+ {
+ if ( Gia_ObjFaninC1(pObj) == (int)pFan1->fMark0 ) // justified
+ return 1;
+ return Cec_ManCheckSat_rec( p, pFan0, Gia_ObjFaninC0(pObj) );
+ }
+ return Cec_ManCheckSat_rec( p, pFan0, Gia_ObjFaninC0(pObj) );
+}
+void Cec_ManSimBack( Gia_Man_t * p )
+{
+ abctime clk = Abc_Clock();
+ Vec_Wrd_t * vValues = Vec_WrdStart( Gia_ManObjNum(p) );
+ Gia_Obj_t * pObj;
+ int i, Count = 0;
+ word Res;
+ Gia_ManSetPhase( p );
+ //Gia_ManForEachAnd( p, pObj, i )
+ // printf( "%d", pObj->fPhase );
+ //printf( "\n" );
+ //return;
+
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ Gia_ManIncrementTravId(p);
+ //Gia_ManCleanMark0( p );
+ Res = Cec_ManCheckSat_rec( p, pObj, !pObj->fPhase );
+ //if ( Res )
+ // Cec_ObjSatVerify( p, pObj, !pObj->fPhase );
+
+ //Res = Cec_ManCheckSat2_rec( p, pObj, !pObj->fPhase ? ~(word)0 : 0, vValues );
+ //if ( Res )
+ // Cec_ObjSatVerify2( p, pObj, !pObj->fPhase, Res );
+
+ Count += (int)(Res > 0);
+ }
+ Vec_WrdFree( vValues );
+ printf( "Obj = %6d. SAT = %6d. ", Gia_ManAndNum(p), Count );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/cec/module.make b/src/proof/cec/module.make
index 82e0de74..38106e5e 100644
--- a/src/proof/cec/module.make
+++ b/src/proof/cec/module.make
@@ -6,6 +6,7 @@ SRC += src/proof/cec/cecCec.c \
src/proof/cec/cecIso.c \
src/proof/cec/cecMan.c \
src/proof/cec/cecPat.c \
+ src/proof/cec/cecSat.c \
src/proof/cec/cecSeq.c \
src/proof/cec/cecSolve.c \
src/proof/cec/cecSplit.c \
diff --git a/src/proof/fra/fraCec.c b/src/proof/fra/fraCec.c
index 130036a6..84f37930 100644
--- a/src/proof/fra/fraCec.c
+++ b/src/proof/fra/fraCec.c
@@ -547,17 +547,17 @@ int Fra_FraigCecTop( Aig_Man_t * pMan1, Aig_Man_t * pMan2, int nConfLimit, int n
// report the miter
if ( RetValue == 1 )
{
- printf( "Networks are equivalent. " );
+ printf( "Networks are equivalent. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else if ( RetValue == 0 )
{
- printf( "Networks are NOT EQUIVALENT. " );
+ printf( "Networks are NOT EQUIVALENT. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
else
{
- printf( "Networks are UNDECIDED. " );
+ printf( "Networks are UNDECIDED. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
fflush( stdout );
diff --git a/src/proof/fra/fraSec.c b/src/proof/fra/fraSec.c
index 06011d2e..7e382fc8 100644
--- a/src/proof/fra/fraSec.c
+++ b/src/proof/fra/fraSec.c
@@ -606,7 +606,7 @@ finish:
{
if ( !pParSec->fSilent )
{
- printf( "Networks are equivalent. " );
+ printf( "Networks are equivalent. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
if ( pParSec->fReportSolution && !pParSec->fRecursive )
@@ -630,7 +630,7 @@ ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
if ( !pParSec->fSilent )
{
- printf( "Networks are NOT EQUIVALENT. " );
+ printf( "Networks are NOT EQUIVALENT. " );
ABC_PRT( "Time", Abc_Clock() - clkTotal );
}
if ( pParSec->fReportSolution && !pParSec->fRecursive )
diff --git a/src/proof/pdr/module.make b/src/proof/pdr/module.make
index 5bee83f8..1dee93aa 100644
--- a/src/proof/pdr/module.make
+++ b/src/proof/pdr/module.make
@@ -1,7 +1,9 @@
SRC += src/proof/pdr/pdrCnf.c \
src/proof/pdr/pdrCore.c \
+ src/proof/pdr/pdrIncr.c \
src/proof/pdr/pdrInv.c \
src/proof/pdr/pdrMan.c \
src/proof/pdr/pdrSat.c \
src/proof/pdr/pdrTsim.c \
- src/proof/pdr/pdrUtil.c
+ src/proof/pdr/pdrTsim2.c \
+ src/proof/pdr/pdrUtil.c
diff --git a/src/proof/pdr/pdr.h b/src/proof/pdr/pdr.h
index 529a161f..51b04606 100644
--- a/src/proof/pdr/pdr.h
+++ b/src/proof/pdr/pdr.h
@@ -49,14 +49,23 @@ struct Pdr_Par_t_
int nTimeOut; // timeout in seconds
int nTimeOutGap; // approximate timeout in seconds since the last change
int nTimeOutOne; // approximate timeout in seconds per one output
+ int nRandomSeed; // value to seed the SAT solver with
int fTwoRounds; // use two rounds for generalization
int fMonoCnf; // monolythic CNF
+ int fNewXSim; // updated X-valued simulation
+ int fFlopPrio; // use structural flop priorities
+ int fFlopOrder; // order flops for 'analyze_final' during generalization
int fDumpInv; // dump inductive invariant
int fUseSupp; // use support in the invariant
int fShortest; // forces bug traces to be shortest
int fShiftStart; // allows clause pushing to start from an intermediate frame
int fReuseProofOblig; // reuses proof-obligationgs in the last timeframe
+ int fSimpleGeneral; // simplified generalization
int fSkipGeneral; // skips expensive generalization step
+ int fSkipDown; // skips the application of down
+ int fCtgs; // handle CTGs in down
+ int fUseAbs; // use abstraction
+ int fUseSimpleRef; // simplified CEX refinement
int fVerbose; // verbose output`
int fVeryVerbose; // very verbose output
int fNotVerbose; // not printing line by line progress
diff --git a/src/proof/pdr/pdrCore.c b/src/proof/pdr/pdrCore.c
index c020c56a..501f9be6 100644
--- a/src/proof/pdr/pdrCore.c
+++ b/src/proof/pdr/pdrCore.c
@@ -20,6 +20,7 @@
#include "pdrInt.h"
#include "base/main/main.h"
+#include "misc/hash/hash.h"
ABC_NAMESPACE_IMPL_START
@@ -57,12 +58,20 @@ void Pdr_ManSetDefaultParams( Pdr_Par_t * pPars )
pPars->nConfLimit = 0; // limit on SAT solver conflicts
pPars->nConfGenLimit = 0; // limit on SAT solver conflicts during generalization
pPars->nRestLimit = 0; // limit on the number of proof-obligations
+ pPars->nRandomSeed = 91648253; // value to seed the SAT solver with
pPars->fTwoRounds = 0; // use two rounds for generalization
pPars->fMonoCnf = 0; // monolythic CNF
+ pPars->fNewXSim = 0; // updated X-valued simulation
+ pPars->fFlopPrio = 0; // use structural flop priorities
+ pPars->fFlopOrder = 0; // order flops for 'analyze_final' during generalization
pPars->fDumpInv = 0; // dump inductive invariant
pPars->fUseSupp = 1; // using support variables in the invariant
pPars->fShortest = 0; // forces bug traces to be shortest
pPars->fUsePropOut = 1; // use property output
+ pPars->fSkipDown = 1; // apply down in generalization
+ pPars->fCtgs = 0; // handle CTGs in down
+ pPars->fUseAbs = 0; // use abstraction
+ pPars->fUseSimpleRef = 0; // simplified CEX refinement
pPars->fVerbose = 0; // verbose output
pPars->fVeryVerbose = 0; // very verbose output
pPars->fNotVerbose = 0; // not printing line-by-line progress
@@ -118,7 +127,7 @@ Pdr_Set_t * Pdr_ManReduceClause( Pdr_Man_t * p, int k, Pdr_Set_t * pCube )
// make sure the cube works
{
int RetValue;
- RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0 );
+ RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0, 1 );
assert( RetValue );
}
*/
@@ -165,7 +174,7 @@ int Pdr_ManPushClauses( Pdr_Man_t * p )
}
// check if the clause can be moved to the next frame
- RetValue2 = Pdr_ManCheckCube( p, k, pCubeK, NULL, 0, 0 );
+ RetValue2 = Pdr_ManCheckCube( p, k, pCubeK, NULL, 0, 0, 1 );
if ( RetValue2 == -1 )
return -1;
if ( !RetValue2 )
@@ -296,6 +305,213 @@ int * Pdr_ManSortByPriority( Pdr_Man_t * p, Pdr_Set_t * pCube )
/**Function*************************************************************
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int ZPdr_ManSimpleMic( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube )
+{
+ int * pOrder;
+ int i, j, Lit, RetValue;
+ Pdr_Set_t * pCubeTmp;
+ // perform generalization
+ if ( p->pPars->fSkipGeneral )
+ return 0;
+
+ // sort literals by their occurences
+ pOrder = Pdr_ManSortByPriority( p, *ppCube );
+ // try removing literals
+ for ( j = 0; j < (*ppCube)->nLits; j++ )
+ {
+ // use ordering
+ // i = j;
+ i = pOrder[j];
+
+ assert( (*ppCube)->Lits[i] != -1 );
+ // check init state
+ if ( Pdr_SetIsInit(*ppCube, i) )
+ continue;
+ // try removing this literal
+ Lit = (*ppCube)->Lits[i]; (*ppCube)->Lits[i] = -1;
+ RetValue = Pdr_ManCheckCube( p, k, *ppCube, NULL, p->pPars->nConfLimit, 0, 1 );
+ if ( RetValue == -1 )
+ return -1;
+ (*ppCube)->Lits[i] = Lit;
+ if ( RetValue == 0 )
+ continue;
+
+ // success - update the cube
+ *ppCube = Pdr_SetCreateFrom( pCubeTmp = *ppCube, i );
+ Pdr_SetDeref( pCubeTmp );
+ assert( (*ppCube)->nLits > 0 );
+
+ // get the ordering by decreasing priority
+ pOrder = Pdr_ManSortByPriority( p, *ppCube );
+ j--;
+ }
+ return 0;
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int ZPdr_ManDown( Pdr_Man_t * p, int k, Pdr_Set_t ** ppCube, Pdr_Set_t * pPred, Hash_Int_t * keep, Pdr_Set_t * pIndCube, int * added )
+{
+ int RetValue = 0, CtgRetValue, i, ctgAttempts, l, micResult;
+ int kMax = Vec_PtrSize(p->vSolvers)-1;
+ Pdr_Set_t * pCubeTmp, * pCubeMin, * pCtg;
+ while ( RetValue == 0 )
+ {
+ ctgAttempts = 0;
+ while ( p->pPars->fCtgs && RetValue == 0 && k > 1 && ctgAttempts < 3 )
+ {
+ pCtg = Pdr_SetDup( pPred );
+ //Check CTG for inductiveness
+ if ( Pdr_SetIsInit( pCtg, -1 ) )
+ {
+ Pdr_SetDeref( pCtg );
+ break;
+ }
+ if (*added == 0)
+ {
+ for ( i = 1; i <= k; i++ )
+ Pdr_ManSolverAddClause( p, i, pIndCube);
+ *added = 1;
+ }
+ ctgAttempts++;
+ CtgRetValue = Pdr_ManCheckCube( p, k-1, pCtg, NULL, p->pPars->nConfLimit, 0, 1 );
+ if ( CtgRetValue != 1 )
+ {
+ Pdr_SetDeref( pCtg );
+ break;
+ }
+ pCubeMin = Pdr_ManReduceClause( p, k-1, pCtg );
+ if ( pCubeMin == NULL )
+ pCubeMin = Pdr_SetDup ( pCtg );
+
+ for ( l = k; l < kMax; l++ )
+ if ( !Pdr_ManCheckCube( p, l, pCubeMin, NULL, 0, 0, 1 ) )
+ break;
+ micResult = ZPdr_ManSimpleMic( p, l-1, &pCubeMin );
+ assert ( micResult != -1 );
+
+ // add new clause
+ if ( p->pPars->fVeryVerbose )
+ {
+ Abc_Print( 1, "Adding cube " );
+ Pdr_SetPrint( stdout, pCubeMin, Aig_ManRegNum(p->pAig), NULL );
+ Abc_Print( 1, " to frame %d.\n", l );
+ }
+ // set priority flops
+ for ( i = 0; i < pCubeMin->nLits; i++ )
+ {
+ assert( pCubeMin->Lits[i] >= 0 );
+ assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) );
+ if ( (Vec_IntEntry(p->vPrio, pCubeMin->Lits[i] / 2) >> p->nPrioShift) == 0 )
+ p->nAbsFlops++;
+ Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 << p->nPrioShift );
+ }
+
+ Vec_VecPush( p->vClauses, l, pCubeMin ); // consume ref
+ p->nCubes++;
+ // add clause
+ for ( i = 1; i <= l; i++ )
+ Pdr_ManSolverAddClause( p, i, pCubeMin );
+ Pdr_SetDeref( pPred );
+ RetValue = Pdr_ManCheckCube( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 );
+ assert( RetValue >= 0 );
+ Pdr_SetDeref( pCtg );
+ if ( RetValue == 1 )
+ {
+ //printf ("IT'S A ONE\n");
+ return 1;
+ }
+ }
+
+ //join
+ if ( p->pPars->fVeryVerbose )
+ {
+ printf("Cube:\n");
+ ZPdr_SetPrint( *ppCube );
+ printf("\nPred:\n");
+ ZPdr_SetPrint( pPred );
+ }
+ *ppCube = ZPdr_SetIntersection( pCubeTmp = *ppCube, pPred, keep );
+ Pdr_SetDeref( pCubeTmp );
+ Pdr_SetDeref( pPred );
+ if ( *ppCube == NULL )
+ return 0;
+ if ( p->pPars->fVeryVerbose )
+ {
+ printf("Intersection:\n");
+ ZPdr_SetPrint( *ppCube );
+ }
+ if ( Pdr_SetIsInit( *ppCube, -1 ) )
+ {
+ if ( p->pPars->fVeryVerbose )
+ printf ("Failed initiation\n");
+ return 0;
+ }
+ RetValue = Pdr_ManCheckCube( p, k, *ppCube, &pPred, p->pPars->nConfLimit, 0, 1 );
+ if ( RetValue == -1 )
+ return -1;
+ if ( RetValue == 1 )
+ {
+ //printf ("*********IT'S A ONE\n");
+ break;
+ }
+ if ( RetValue == 0 && (*ppCube)->nLits == 1)
+ {
+ Pdr_SetDeref( pPred ); // fixed memory leak
+ // A workaround for the incomplete assignment returned by the SAT
+ // solver
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Specialized sorting of flops based on cost.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Vec_IntSelectSortCostReverseLit( int * pArray, int nSize, Vec_Int_t * vCosts )
+{
+ int i, j, best_i;
+ for ( i = 0; i < nSize-1; i++ )
+ {
+ best_i = i;
+ for ( j = i+1; j < nSize; j++ )
+ if ( Vec_IntEntry(vCosts, Abc_Lit2Var(pArray[j])) > Vec_IntEntry(vCosts, Abc_Lit2Var(pArray[best_i])) )
+ best_i = j;
+ ABC_SWAP( int, pArray[i], pArray[best_i] );
+ }
+}
+
+/**Function*************************************************************
+
Synopsis [Returns 1 if the state could be blocked.]
Description []
@@ -307,20 +523,28 @@ int * Pdr_ManSortByPriority( Pdr_Man_t * p, Pdr_Set_t * pCube )
***********************************************************************/
int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, Pdr_Set_t ** ppCubeMin )
{
- Pdr_Set_t * pCubeMin, * pCubeTmp = NULL;
- int i, j, n, Lit, RetValue;
+ Pdr_Set_t * pCubeMin, * pCubeTmp = NULL, * pPred = NULL, * pCubeCpy = NULL;
+ int i, j, Lit, RetValue;
abctime clk = Abc_Clock();
int * pOrder;
+ int added = 0;
+ Hash_Int_t * keep = NULL;
// if there is no induction, return
*ppCubeMin = NULL;
- RetValue = Pdr_ManCheckCube( p, k, pCube, ppPred, p->pPars->nConfLimit, 0 );
+ if ( p->pPars->fFlopOrder )
+ Vec_IntSelectSortCostReverseLit( pCube->Lits, pCube->nLits, p->vPrio );
+ RetValue = Pdr_ManCheckCube( p, k, pCube, ppPred, p->pPars->nConfLimit, 0, 1 );
+ if ( p->pPars->fFlopOrder )
+ Vec_IntSelectSort( pCube->Lits, pCube->nLits );
if ( RetValue == -1 )
return -1;
if ( RetValue == 0 )
{
- p->tGeneral += Abc_Clock() - clk;
+ p->tGeneral += clock() - clk;
return 0;
}
+
+ keep = p->pPars->fSkipDown ? NULL : Hash_IntAlloc( 1 );
// reduce clause using assumptions
// pCubeMin = Pdr_SetDup( pCube );
@@ -331,6 +555,16 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP
// perform generalization
if ( !p->pPars->fSkipGeneral )
{
+ // assume the unminimized cube
+ if ( p->pPars->fSimpleGeneral )
+ {
+ sat_solver * pSat = Pdr_ManFetchSolver( p, k );
+ Vec_Int_t * vLits1 = Pdr_ManCubeToLits( p, k, pCubeMin, 1, 0 );
+ int RetValue1 = sat_solver_addclause( pSat, Vec_IntArray(vLits1), Vec_IntArray(vLits1) + Vec_IntSize(vLits1) );
+ assert( RetValue1 == 1 );
+ sat_solver_compress( pSat );
+ }
+
// sort literals by their occurences
pOrder = Pdr_ManSortByPriority( p, pCubeMin );
// try removing literals
@@ -340,13 +574,23 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP
// i = j;
i = pOrder[j];
- // check init state
assert( pCubeMin->Lits[i] != -1 );
+ if ( keep && Hash_IntExists( keep, pCubeMin->Lits[i] ) )
+ {
+ //printf("Undroppable\n");
+ continue;
+ }
+
+ // check init state
if ( Pdr_SetIsInit(pCubeMin, i) )
continue;
+
// try removing this literal
- Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1;
- RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1 );
+ Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1;
+ if ( p->pPars->fSkipDown )
+ RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 1, !p->pPars->fSimpleGeneral );
+ else
+ RetValue = Pdr_ManCheckCube( p, k, pCubeMin, &pPred, p->pPars->nConfLimit, 1, !p->pPars->fSimpleGeneral );
if ( RetValue == -1 )
{
Pdr_SetDeref( pCubeMin );
@@ -354,21 +598,58 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP
}
pCubeMin->Lits[i] = Lit;
if ( RetValue == 0 )
+ {
+ if ( p->pPars->fSkipDown )
+ continue;
+ pCubeCpy = Pdr_SetCreateFrom( pCubeMin, i );
+ RetValue = ZPdr_ManDown( p, k, &pCubeCpy, pPred, keep, pCubeMin, &added );
+ if ( p->pPars->fCtgs )
+ //CTG handling code messes up with the internal order array
+ pOrder = Pdr_ManSortByPriority( p, pCubeMin );
+ if ( RetValue == -1 )
+ {
+ Pdr_SetDeref( pCubeMin );
+ Pdr_SetDeref( pCubeCpy );
+ Pdr_SetDeref( pPred );
+ return -1;
+ }
+ if ( RetValue == 0 )
+ {
+ if ( keep )
+ Hash_IntWriteEntry( keep, pCubeMin->Lits[i], 0 );
+ if ( pCubeCpy )
+ Pdr_SetDeref( pCubeCpy );
+ continue;
+ }
+ //Inductive subclause
+ added = 0;
+ Pdr_SetDeref( pCubeMin );
+ pCubeMin = pCubeCpy;
+ assert( pCubeMin->nLits > 0 );
+ pOrder = Pdr_ManSortByPriority( p, pCubeMin );
+ j = -1;
continue;
-
- // remove j-th entry
- for ( n = j; n < pCubeMin->nLits-1; n++ )
- pOrder[n] = pOrder[n+1];
- j--;
+ }
+ added = 0;
// success - update the cube
pCubeMin = Pdr_SetCreateFrom( pCubeTmp = pCubeMin, i );
Pdr_SetDeref( pCubeTmp );
assert( pCubeMin->nLits > 0 );
- i--;
- // get the ordering by decreasing priorit
+ // assume the minimized cube
+ if ( p->pPars->fSimpleGeneral )
+ {
+ sat_solver * pSat = Pdr_ManFetchSolver( p, k );
+ Vec_Int_t * vLits1 = Pdr_ManCubeToLits( p, k, pCubeMin, 1, 0 );
+ int RetValue1 = sat_solver_addclause( pSat, Vec_IntArray(vLits1), Vec_IntArray(vLits1) + Vec_IntSize(vLits1) );
+ assert( RetValue1 == 1 );
+ sat_solver_compress( pSat );
+ }
+
+ // get the ordering by decreasing priority
pOrder = Pdr_ManSortByPriority( p, pCubeMin );
+ j--;
}
if ( p->pPars->fTwoRounds )
@@ -383,8 +664,8 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP
if ( Pdr_SetIsInit(pCubeMin, i) )
continue;
// try removing this literal
- Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1;
- RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 0 );
+ Lit = pCubeMin->Lits[i]; pCubeMin->Lits[i] = -1;
+ RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, p->pPars->nConfLimit, 0, 1 );
if ( RetValue == -1 )
{
Pdr_SetDeref( pCubeMin );
@@ -394,25 +675,30 @@ int Pdr_ManGeneralize( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppP
if ( RetValue == 0 )
continue;
- // remove j-th entry
- for ( n = j; n < pCubeMin->nLits-1; n++ )
- pOrder[n] = pOrder[n+1];
- j--;
-
// success - update the cube
pCubeMin = Pdr_SetCreateFrom( pCubeTmp = pCubeMin, i );
Pdr_SetDeref( pCubeTmp );
assert( pCubeMin->nLits > 0 );
- i--;
- // get the ordering by decreasing priorit
+ // get the ordering by decreasing priority
pOrder = Pdr_ManSortByPriority( p, pCubeMin );
+ j--;
}
}
assert( ppCubeMin != NULL );
+ if ( p->pPars->fVeryVerbose )
+ {
+ printf("Cube:\n");
+ for ( i = 0; i < pCubeMin->nLits; i++)
+ {
+ printf ("%d ", pCubeMin->Lits[i]);
+ }
+ printf("\n");
+ }
*ppCubeMin = pCubeMin;
p->tGeneral += Abc_Clock() - clk;
+ if ( keep ) Hash_IntFree( keep );
return 1;
}
@@ -444,7 +730,7 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube )
{
Counter++;
pThis = Pdr_QueueHead( p );
- if ( pThis->iFrame == 0 )
+ if ( pThis->iFrame == 0 || (p->pPars->fUseAbs && Pdr_SetIsInit(pThis->pState, -1)) )
return 0; // SAT
if ( pThis->iFrame > kMax ) // finished this level
return 1;
@@ -497,7 +783,7 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube )
assert( pPred == NULL );
for ( k = pThis->iFrame; k < kMax; k++ )
{
- RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0 );
+ RetValue = Pdr_ManCheckCube( p, k, pCubeMin, NULL, 0, 0, 1 );
if ( RetValue == -1 )
{
Pdr_OblDeref( pThis );
@@ -518,7 +804,9 @@ int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube )
{
assert( pCubeMin->Lits[i] >= 0 );
assert( (pCubeMin->Lits[i] / 2) < Aig_ManRegNum(p->pAig) );
- Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 );
+ if ( (Vec_IntEntry(p->vPrio, pCubeMin->Lits[i] / 2) >> p->nPrioShift) == 0 )
+ p->nAbsFlops++;
+ Vec_IntAddToEntry( p->vPrio, pCubeMin->Lits[i] / 2, 1 << p->nPrioShift );
}
Vec_VecPush( p->vClauses, k, pCubeMin ); // consume ref
p->nCubes++;
@@ -577,29 +865,43 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
Pdr_Set_t * pCube = NULL;
Aig_Obj_t * pObj;
Abc_Cex_t * pCexNew;
- int k, RetValue = -1;
+ int iFrame, RetValue = -1;
int nOutDigits = Abc_Base10Log( Saig_ManPoNum(p->pAig) );
abctime clkStart = Abc_Clock(), clkOne = 0;
p->timeToStop = p->pPars->nTimeOut ? p->pPars->nTimeOut * CLOCKS_PER_SEC + Abc_Clock(): 0;
assert( Vec_PtrSize(p->vSolvers) == 0 );
// in the multi-output mode, mark trivial POs (those fed by const0) as solved
if ( p->pPars->fSolveAll )
- Saig_ManForEachPo( p->pAig, pObj, k )
+ Saig_ManForEachPo( p->pAig, pObj, iFrame )
if ( Aig_ObjChild0(pObj) == Aig_ManConst0(p->pAig) )
{
- Vec_IntWriteEntry( p->pPars->vOutMap, k, 1 ); // unsat
+ Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat
p->pPars->nProveOuts++;
if ( p->pPars->fUseBridge )
- Gia_ManToBridgeResult( stdout, 1, NULL, k );
+ Gia_ManToBridgeResult( stdout, 1, NULL, iFrame );
}
// create the first timeframe
p->pPars->timeLastSolved = Abc_Clock();
- Pdr_ManCreateSolver( p, (k = 0) );
+ Pdr_ManCreateSolver( p, (iFrame = 0) );
while ( 1 )
{
- p->nFrames = k;
- assert( k == Vec_PtrSize(p->vSolvers)-1 );
- p->iUseFrame = Abc_MaxInt(k, 1);
+ int fRefined = 0;
+ if ( p->pPars->fUseAbs && p->vAbsFlops == NULL && iFrame == 1 )
+ {
+// int i, Prio;
+ assert( p->vAbsFlops == NULL );
+ p->vAbsFlops = Vec_IntStart( Saig_ManRegNum(p->pAig) );
+ p->vMapFf2Ppi = Vec_IntStartFull( Saig_ManRegNum(p->pAig) );
+ p->vMapPpi2Ff = Vec_IntAlloc( 100 );
+// Vec_IntForEachEntry( p->vPrio, Prio, i )
+// if ( Prio >> p->nPrioShift )
+// Vec_IntWriteEntry( p->vAbsFlops, i, 1 );
+ }
+ //if ( p->pPars->fUseAbs && p->vAbsFlops )
+ // printf( "Starting frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) );
+ p->nFrames = iFrame;
+ assert( iFrame == Vec_PtrSize(p->vSolvers)-1 );
+ p->iUseFrame = Abc_MaxInt(iFrame, 1);
Saig_ManForEachPo( p->pAig, pObj, p->iOutCur )
{
// skip disproved outputs
@@ -616,16 +918,16 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
{
if ( !p->pPars->fSolveAll )
{
- pCexNew = Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), k*Saig_ManPoNum(p->pAig)+p->iOutCur );
+ pCexNew = Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur );
p->pAig->pSeqModel = pCexNew;
return 0; // SAT
}
- pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), k*Saig_ManPoNum(p->pAig)+p->iOutCur ) : (Abc_Cex_t *)(ABC_PTRINT_T)1;
+ pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur ) : (Abc_Cex_t *)(ABC_PTRINT_T)1;
p->pPars->nFailOuts++;
if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, 0 );
if ( !p->pPars->fNotVerbose )
Abc_Print( 1, "Output %*d was trivially asserted in frame %2d (solved %*d out of %*d outputs).\n",
- nOutDigits, p->iOutCur, k, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) );
+ nOutDigits, p->iOutCur, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) );
assert( Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL );
if ( p->pPars->fUseBridge )
Gia_ManToBridgeResult( stdout, 0, pCexNew, pCexNew->iPo );
@@ -635,8 +937,8 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( !p->pPars->fSilent )
- Abc_Print( 1, "Quitting due to callback on fail.\n" );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( p->pPars->nFailOuts + p->pPars->nDropOuts == Saig_ManPoNum(p->pAig) )
@@ -658,11 +960,11 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( !p->pPars->fSilent )
- Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
- RetValue = Pdr_ManCheckCube( p, k, NULL, &pCube, p->pPars->nConfLimit, 0 );
+ RetValue = Pdr_ManCheckCube( p, iFrame, NULL, &pCube, p->pPars->nConfLimit, 0, 1 );
if ( RetValue == 1 )
break;
if ( RetValue == -1 )
@@ -670,9 +972,9 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( p->timeToStop && Abc_Clock() > p->timeToStop )
- Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut );
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
- Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap );
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne )
{
Pdr_QueueClean( p );
@@ -680,10 +982,10 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
break; // keep solving
}
else if ( p->pPars->nConfLimit )
- Abc_Print( 1, "Reached conflict limit (%d).\n", p->pPars->nConfLimit );
+ Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame );
else if ( p->pPars->fVerbose )
- Abc_Print( 1, "Computation cancelled by the callback.\n" );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( RetValue == 0 )
@@ -694,9 +996,9 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( p->timeToStop && Abc_Clock() > p->timeToStop )
- Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut );
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
- Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap );
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne )
{
Pdr_QueueClean( p );
@@ -704,25 +1006,36 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
break; // keep solving
}
else if ( p->pPars->nConfLimit )
- Abc_Print( 1, "Reached conflict limit (%d).\n", p->pPars->nConfLimit );
+ Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame );
else if ( p->pPars->fVerbose )
- Abc_Print( 1, "Computation cancelled by the callback.\n" );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( RetValue == 0 )
{
if ( fPrintClauses )
{
- Abc_Print( 1, "*** Clauses after frame %d:\n", k );
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
Pdr_ManPrintClauses( p, 0 );
}
- if ( p->pPars->fVerbose )
+ if ( p->pPars->fVerbose && !p->pPars->fUseAbs )
Pdr_ManPrintProgress( p, !p->pPars->fSolveAll, Abc_Clock() - clkStart );
- p->pPars->iFrame = k;
+ p->pPars->iFrame = iFrame;
if ( !p->pPars->fSolveAll )
{
- p->pAig->pSeqModel = Pdr_ManDeriveCex(p);
+ abctime clk = Abc_Clock();
+ Abc_Cex_t * pCex = Pdr_ManDeriveCexAbs(p);
+ p->tAbs += Abc_Clock() - clk;
+ if ( pCex == NULL )
+ {
+ assert( p->pPars->fUseAbs );
+ Pdr_QueueClean( p );
+ pCube = NULL;
+ fRefined = 1;
+ break; // keep solving
+ }
+ p->pAig->pSeqModel = pCex;
return 0; // SAT
}
p->pPars->nFailOuts++;
@@ -737,13 +1050,13 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( !p->pPars->fSilent )
- Abc_Print( 1, "Quitting due to callback on fail.\n" );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( !p->pPars->fNotVerbose )
Abc_Print( 1, "Output %*d was asserted in frame %2d (%2d) (solved %*d out of %*d outputs).\n",
- nOutDigits, p->iOutCur, k, k, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) );
+ nOutDigits, p->iOutCur, iFrame, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) );
if ( p->pPars->nFailOuts == Saig_ManPoNum(p->pAig) )
return 0; // all SAT
Pdr_QueueClean( p );
@@ -754,6 +1067,8 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
Pdr_ManPrintProgress( p, 0, Abc_Clock() - clkStart );
}
}
+ if ( fRefined )
+ break;
if ( p->pTime4Outs )
{
abctime timeSince = Abc_Clock() - clkOne;
@@ -765,22 +1080,32 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( p->pPars->vOutMap )
Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, -1 );
if ( !p->pPars->fNotVerbose )
- Abc_Print( 1, "Timing out on output %*d.\n", nOutDigits, p->iOutCur );
+ Abc_Print( 1, "Timing out on output %*d in frame %d.\n", nOutDigits, p->iOutCur, iFrame );
}
p->timeToStopOne = 0;
}
}
-
+ if ( p->pPars->fUseAbs && p->vAbsFlops && !fRefined )
+ {
+ int i, Used;
+ Vec_IntForEachEntry( p->vAbsFlops, Used, i )
+ if ( Used && (Vec_IntEntry(p->vPrio, i) >> p->nPrioShift) == 0 )
+ Vec_IntWriteEntry( p->vAbsFlops, i, 0 );
+ }
if ( p->pPars->fVerbose )
- Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ Pdr_ManPrintProgress( p, !fRefined, Abc_Clock() - clkStart );
+ if ( fRefined )
+ continue;
+ //if ( p->pPars->fUseAbs && p->vAbsFlops )
+ // printf( "Finished frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) );
// open a new timeframe
p->nQueLim = p->pPars->nRestLimit;
assert( pCube == NULL );
- Pdr_ManSetPropertyOutput( p, k );
- Pdr_ManCreateSolver( p, ++k );
+ Pdr_ManSetPropertyOutput( p, iFrame );
+ Pdr_ManCreateSolver( p, ++iFrame );
if ( fPrintClauses )
{
- Abc_Print( 1, "*** Clauses after frame %d:\n", k );
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
Pdr_ManPrintClauses( p, 0 );
}
// push clauses into this timeframe
@@ -792,11 +1117,11 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
if ( !p->pPars->fSilent )
{
if ( p->timeToStop && Abc_Clock() > p->timeToStop )
- Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut );
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
else
- Abc_Print( 1, "Reached conflict limit (%d).\n", p->pPars->nConfLimit );
+ Abc_Print( 1, "Reached conflict limit (%d) in frame.\n", p->pPars->nConfLimit, iFrame );
}
- p->pPars->iFrame = k;
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( RetValue )
@@ -807,17 +1132,17 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
Pdr_ManReportInvariant( p );
if ( !p->pPars->fSilent )
Pdr_ManVerifyInvariant( p );
- p->pPars->iFrame = k;
+ p->pPars->iFrame = iFrame;
// count the number of UNSAT outputs
p->pPars->nProveOuts = Saig_ManPoNum(p->pAig) - p->pPars->nFailOuts - p->pPars->nDropOuts;
// convert previously 'unknown' into 'unsat'
if ( p->pPars->vOutMap )
- for ( k = 0; k < Saig_ManPoNum(p->pAig); k++ )
- if ( Vec_IntEntry(p->pPars->vOutMap, k) == -2 ) // unknown
+ for ( iFrame = 0; iFrame < Saig_ManPoNum(p->pAig); iFrame++ )
+ if ( Vec_IntEntry(p->pPars->vOutMap, iFrame) == -2 ) // unknown
{
- Vec_IntWriteEntry( p->pPars->vOutMap, k, 1 ); // unsat
+ Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat
if ( p->pPars->fUseBridge )
- Gia_ManToBridgeResult( stdout, 1, NULL, k );
+ Gia_ManToBridgeResult( stdout, 1, NULL, iFrame );
}
if ( p->pPars->nProveOuts == Saig_ManPoNum(p->pAig) )
return 1; // UNSAT
@@ -831,44 +1156,44 @@ int Pdr_ManSolveInt( Pdr_Man_t * p )
// check termination
if ( p->pPars->pFuncStop && p->pPars->pFuncStop(p->pPars->RunId) )
{
- p->pPars->iFrame = k;
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( p->timeToStop && Abc_Clock() > p->timeToStop )
{
if ( fPrintClauses )
{
- Abc_Print( 1, "*** Clauses after frame %d:\n", k );
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
Pdr_ManPrintClauses( p, 0 );
}
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( !p->pPars->fSilent )
- Abc_Print( 1, "Reached timeout (%d seconds).\n", p->pPars->nTimeOut );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
{
if ( fPrintClauses )
{
- Abc_Print( 1, "*** Clauses after frame %d:\n", k );
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
Pdr_ManPrintClauses( p, 0 );
}
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( !p->pPars->fSilent )
- Abc_Print( 1, "Reached gap timeout (%d seconds).\n", p->pPars->nTimeOutGap );
- p->pPars->iFrame = k;
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
+ p->pPars->iFrame = iFrame;
return -1;
}
- if ( p->pPars->nFrameMax && k >= p->pPars->nFrameMax )
+ if ( p->pPars->nFrameMax && iFrame >= p->pPars->nFrameMax )
{
if ( p->pPars->fVerbose )
Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
if ( !p->pPars->fSilent )
Abc_Print( 1, "Reached limit on the number of timeframes (%d).\n", p->pPars->nFrameMax );
- p->pPars->iFrame = k;
+ p->pPars->iFrame = iFrame;
return -1;
}
}
@@ -922,11 +1247,12 @@ int Pdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars )
}
if ( p->pPars->fDumpInv )
{
- Abc_FrameSetCnf( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) );
- Abc_FrameSetStr( Pdr_ManDumpString(p) );
- Abc_FrameSetInv( Pdr_ManCountFlopsInv(p) );
- Pdr_ManDumpClauses( p, (char *)"inv.pla", RetValue==1 );
+ char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla");
+ Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) );
+ Pdr_ManDumpClauses( p, pFileName, RetValue==1 );
}
+ else if ( RetValue == 1 )
+ Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) );
p->tTotal += Abc_Clock() - clk;
Pdr_ManStop( p );
pPars->iFrame--;
diff --git a/src/proof/pdr/pdrIncr.c b/src/proof/pdr/pdrIncr.c
new file mode 100644
index 00000000..3fcd3d31
--- /dev/null
+++ b/src/proof/pdr/pdrIncr.c
@@ -0,0 +1,760 @@
+/**CFile****************************************************************
+
+ FileName [pdrIncr.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Property driven reachability.]
+
+ Synopsis [PDR with incremental solving.]
+
+ Author [Yen-Sheng Ho, Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - Feb. 17, 2017.]
+
+ Revision [$Id: pdrIncr.c$]
+
+***********************************************************************/
+
+#include "pdrInt.h"
+#include "base/main/main.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters );
+extern int Pdr_ManBlockCube( Pdr_Man_t * p, Pdr_Set_t * pCube );
+extern int Pdr_ManPushClauses( Pdr_Man_t * p );
+extern int Gia_ManToBridgeAbort( FILE * pFile, int Size, unsigned char * pBuffer );
+extern int Gia_ManToBridgeResult( FILE * pFile, int Result, Abc_Cex_t * pCex, int iPoProved );
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void IPdr_ManPrintClauses( Vec_Vec_t * vClauses, int kStart, int nRegs )
+{
+ Vec_Ptr_t * vArrayK;
+ Pdr_Set_t * pCube;
+ int i, k, Counter = 0;
+ Vec_VecForEachLevelStart( vClauses, vArrayK, k, kStart )
+ {
+ Vec_PtrSort( vArrayK, (int (*)(void))Pdr_SetCompare );
+ Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCube, i )
+ {
+ Abc_Print( 1, "C=%4d. F=%4d ", Counter++, k );
+ Pdr_SetPrint( stdout, pCube, nRegs, NULL );
+ Abc_Print( 1, "\n" );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [ Check if each cube c_k in frame k satisfies the query
+ R_{k-1} && T && !c_k && c_k' (must be UNSAT).
+ Return True if all cubes pass the check. ]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IPdr_ManCheckClauses( Pdr_Man_t * p )
+{
+ Pdr_Set_t * pCubeK;
+ Vec_Ptr_t * vArrayK;
+ int j, k, RetValue, kMax = Vec_PtrSize(p->vSolvers);
+ int iStartFrame = 1;
+ int counter = 0;
+
+ Vec_VecForEachLevelStartStop( p->vClauses, vArrayK, k, iStartFrame, kMax )
+ {
+ Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCubeK, j )
+ {
+ ++counter;
+ RetValue = Pdr_ManCheckCube( p, k - 1, pCubeK, NULL, 0, 0, 1 );
+
+ if ( !RetValue ) {
+ printf( "Cube[%d][%d] not inductive!\n", k, j );
+ }
+
+ assert( RetValue == 1 );
+ }
+ }
+
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast )
+{
+ int i, k;
+ Vec_Vec_t * vClausesSaved;
+ Pdr_Set_t * pCla;
+
+ if ( Vec_VecSize( p->vClauses ) == 1 )
+ return NULL;
+ if ( Vec_VecSize( p->vClauses ) == 2 && fDropLast )
+ return NULL;
+
+ if ( fDropLast )
+ vClausesSaved = Vec_VecStart( Vec_VecSize(p->vClauses)-1 );
+ else
+ vClausesSaved = Vec_VecStart( Vec_VecSize(p->vClauses) );
+
+ Vec_VecForEachEntryStartStop( Pdr_Set_t *, p->vClauses, pCla, i, k, 0, Vec_VecSize(vClausesSaved) )
+ Vec_VecPush(vClausesSaved, i, Pdr_SetDup(pCla));
+
+ return vClausesSaved;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+sat_solver * IPdr_ManSetSolver( Pdr_Man_t * p, int k, int nTotal )
+{
+ sat_solver * pSat;
+ Vec_Ptr_t * vArrayK;
+ Pdr_Set_t * pCube;
+ int i, j;
+
+ assert( Vec_PtrSize(p->vSolvers) == k );
+ assert( Vec_IntSize(p->vActVars) == k );
+
+ pSat = zsat_solver_new_seed(p->pPars->nRandomSeed);
+ pSat = Pdr_ManNewSolver( pSat, p, k, (int)(k == 0) );
+ Vec_PtrPush( p->vSolvers, pSat );
+ Vec_IntPush( p->vActVars, 0 );
+
+ // set the property output
+ if ( k < nTotal - 1 )
+ Pdr_ManSetPropertyOutput( p, k );
+
+ if (k == 0)
+ return pSat;
+
+ // add the clauses
+ Vec_VecForEachLevelStart( p->vClauses, vArrayK, i, k )
+ Vec_PtrForEachEntry( Pdr_Set_t *, vArrayK, pCube, j )
+ Pdr_ManSolverAddClause( p, k, pCube );
+ return pSat;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses, Vec_Int_t * vMap )
+{
+ int i;
+
+ assert(vClauses);
+
+ Vec_VecFree(p->vClauses);
+ p->vClauses = vClauses;
+
+ // remap clause literals using mapping (old flop -> new flop) found in array vMap
+ if ( vMap )
+ {
+ Pdr_Set_t * pSet; int j, k;
+ Vec_VecForEachEntry( Pdr_Set_t *, vClauses, pSet, i, j )
+ for ( k = 0; k < pSet->nLits; k++ )
+ pSet->Lits[k] = Abc_Lit2LitV( Vec_IntArray(vMap), pSet->Lits[k] );
+ }
+
+ for ( i = 0; i < Vec_VecSize(p->vClauses); ++i )
+ IPdr_ManSetSolver( p, i, Vec_VecSize( p->vClauses ) );
+
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses )
+{
+ int fPrintClauses = 0;
+ Pdr_Set_t * pCube = NULL;
+ Aig_Obj_t * pObj;
+ Abc_Cex_t * pCexNew;
+ int iFrame, RetValue = -1;
+ int nOutDigits = Abc_Base10Log( Saig_ManPoNum(p->pAig) );
+ abctime clkStart = Abc_Clock(), clkOne = 0;
+ p->timeToStop = p->pPars->nTimeOut ? p->pPars->nTimeOut * CLOCKS_PER_SEC + Abc_Clock(): 0;
+ // assert( Vec_PtrSize(p->vSolvers) == 0 );
+ // in the multi-output mode, mark trivial POs (those fed by const0) as solved
+ if ( p->pPars->fSolveAll )
+ Saig_ManForEachPo( p->pAig, pObj, iFrame )
+ if ( Aig_ObjChild0(pObj) == Aig_ManConst0(p->pAig) )
+ {
+ Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat
+ p->pPars->nProveOuts++;
+ if ( p->pPars->fUseBridge )
+ Gia_ManToBridgeResult( stdout, 1, NULL, iFrame );
+ }
+ // create the first timeframe
+ p->pPars->timeLastSolved = Abc_Clock();
+
+ if ( Vec_VecSize(p->vClauses) == 0 )
+ Pdr_ManCreateSolver( p, (iFrame = 0) );
+ else {
+ iFrame = Vec_VecSize(p->vClauses) - 1;
+
+ if ( fCheckClauses )
+ {
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, "IPDR: Checking the reloaded length-%d trace...", iFrame + 1 ) ;
+ IPdr_ManCheckClauses( p );
+ if ( p->pPars->fVerbose )
+ Abc_Print( 1, " Passed!\n" ) ;
+ }
+
+ if ( fPushClauses )
+ {
+ p->iUseFrame = Abc_MaxInt(iFrame, 1);
+
+ if ( p->pPars->fVerbose )
+ {
+ Abc_Print( 1, "IPDR: Pushing the reloaded clauses. Before:\n" );
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ }
+
+ RetValue = Pdr_ManPushClauses( p );
+
+ if ( p->pPars->fVerbose )
+ {
+ Abc_Print( 1, "IPDR: Finished pushing. After:\n" );
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ }
+
+ if ( RetValue )
+ {
+ Pdr_ManReportInvariant( p );
+ Pdr_ManVerifyInvariant( p );
+ return 1;
+ }
+ }
+ }
+ while ( 1 )
+ {
+ int fRefined = 0;
+ if ( p->pPars->fUseAbs && p->vAbsFlops == NULL && iFrame == 1 )
+ {
+// int i, Prio;
+ assert( p->vAbsFlops == NULL );
+ p->vAbsFlops = Vec_IntStart( Saig_ManRegNum(p->pAig) );
+ p->vMapFf2Ppi = Vec_IntStartFull( Saig_ManRegNum(p->pAig) );
+ p->vMapPpi2Ff = Vec_IntAlloc( 100 );
+// Vec_IntForEachEntry( p->vPrio, Prio, i )
+// if ( Prio >> p->nPrioShift )
+// Vec_IntWriteEntry( p->vAbsFlops, i, 1 );
+ }
+ //if ( p->pPars->fUseAbs && p->vAbsFlops )
+ // printf( "Starting frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) );
+ p->nFrames = iFrame;
+ assert( iFrame == Vec_PtrSize(p->vSolvers)-1 );
+ p->iUseFrame = Abc_MaxInt(iFrame, 1);
+ Saig_ManForEachPo( p->pAig, pObj, p->iOutCur )
+ {
+ // skip disproved outputs
+ if ( p->vCexes && Vec_PtrEntry(p->vCexes, p->iOutCur) )
+ continue;
+ // skip output whose time has run out
+ if ( p->pTime4Outs && p->pTime4Outs[p->iOutCur] == 0 )
+ continue;
+ // check if the output is trivially solved
+ if ( Aig_ObjChild0(pObj) == Aig_ManConst0(p->pAig) )
+ continue;
+ // check if the output is trivially solved
+ if ( Aig_ObjChild0(pObj) == Aig_ManConst1(p->pAig) )
+ {
+ if ( !p->pPars->fSolveAll )
+ {
+ pCexNew = Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur );
+ p->pAig->pSeqModel = pCexNew;
+ return 0; // SAT
+ }
+ pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Abc_CexMakeTriv( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), iFrame*Saig_ManPoNum(p->pAig)+p->iOutCur ) : (Abc_Cex_t *)(ABC_PTRINT_T)1;
+ p->pPars->nFailOuts++;
+ if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, 0 );
+ if ( !p->pPars->fNotVerbose )
+ Abc_Print( 1, "Output %*d was trivially asserted in frame %2d (solved %*d out of %*d outputs).\n",
+ nOutDigits, p->iOutCur, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) );
+ assert( Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL );
+ if ( p->pPars->fUseBridge )
+ Gia_ManToBridgeResult( stdout, 0, pCexNew, pCexNew->iPo );
+ Vec_PtrWriteEntry( p->vCexes, p->iOutCur, pCexNew );
+ if ( p->pPars->pFuncOnFail && p->pPars->pFuncOnFail(p->iOutCur, p->pPars->fStoreCex ? (Abc_Cex_t *)Vec_PtrEntry(p->vCexes, p->iOutCur) : NULL) )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( p->pPars->nFailOuts + p->pPars->nDropOuts == Saig_ManPoNum(p->pAig) )
+ return p->pPars->nFailOuts ? 0 : -1; // SAT or UNDEC
+ p->pPars->timeLastSolved = Abc_Clock();
+ continue;
+ }
+ // try to solve this output
+ if ( p->pTime4Outs )
+ {
+ assert( p->pTime4Outs[p->iOutCur] > 0 );
+ clkOne = Abc_Clock();
+ p->timeToStopOne = p->pTime4Outs[p->iOutCur] + Abc_Clock();
+ }
+ while ( 1 )
+ {
+ if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ RetValue = Pdr_ManCheckCube( p, iFrame, NULL, &pCube, p->pPars->nConfLimit, 0, 1 );
+ if ( RetValue == 1 )
+ break;
+ if ( RetValue == -1 )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( p->timeToStop && Abc_Clock() > p->timeToStop )
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
+ else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
+ else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne )
+ {
+ Pdr_QueueClean( p );
+ pCube = NULL;
+ break; // keep solving
+ }
+ else if ( p->pPars->nConfLimit )
+ Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame );
+ else if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( RetValue == 0 )
+ {
+ RetValue = Pdr_ManBlockCube( p, pCube );
+ if ( RetValue == -1 )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( p->timeToStop && Abc_Clock() > p->timeToStop )
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
+ else if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
+ else if ( p->timeToStopOne && Abc_Clock() > p->timeToStopOne )
+ {
+ Pdr_QueueClean( p );
+ pCube = NULL;
+ break; // keep solving
+ }
+ else if ( p->pPars->nConfLimit )
+ Abc_Print( 1, "Reached conflict limit (%d) in frame %d.\n", p->pPars->nConfLimit, iFrame );
+ else if ( p->pPars->fVerbose )
+ Abc_Print( 1, "Computation cancelled by the callback in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( RetValue == 0 )
+ {
+ if ( fPrintClauses )
+ {
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
+ Pdr_ManPrintClauses( p, 0 );
+ }
+ if ( p->pPars->fVerbose && !p->pPars->fUseAbs )
+ Pdr_ManPrintProgress( p, !p->pPars->fSolveAll, Abc_Clock() - clkStart );
+ p->pPars->iFrame = iFrame;
+ if ( !p->pPars->fSolveAll )
+ {
+ abctime clk = Abc_Clock();
+ Abc_Cex_t * pCex = Pdr_ManDeriveCexAbs(p);
+ p->tAbs += Abc_Clock() - clk;
+ if ( pCex == NULL )
+ {
+ assert( p->pPars->fUseAbs );
+ Pdr_QueueClean( p );
+ pCube = NULL;
+ fRefined = 1;
+ break; // keep solving
+ }
+ p->pAig->pSeqModel = pCex;
+ return 0; // SAT
+ }
+ p->pPars->nFailOuts++;
+ pCexNew = (p->pPars->fUseBridge || p->pPars->fStoreCex) ? Pdr_ManDeriveCex(p) : (Abc_Cex_t *)(ABC_PTRINT_T)1;
+ if ( p->pPars->vOutMap ) Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, 0 );
+ assert( Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL );
+ if ( p->pPars->fUseBridge )
+ Gia_ManToBridgeResult( stdout, 0, pCexNew, pCexNew->iPo );
+ Vec_PtrWriteEntry( p->vCexes, p->iOutCur, pCexNew );
+ if ( p->pPars->pFuncOnFail && p->pPars->pFuncOnFail(p->iOutCur, p->pPars->fStoreCex ? (Abc_Cex_t *)Vec_PtrEntry(p->vCexes, p->iOutCur) : NULL) )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Abc_Print( 1, "Quitting due to callback on fail in frame %d.\n", iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( !p->pPars->fNotVerbose )
+ Abc_Print( 1, "Output %*d was asserted in frame %2d (%2d) (solved %*d out of %*d outputs).\n",
+ nOutDigits, p->iOutCur, iFrame, iFrame, nOutDigits, p->pPars->nFailOuts, nOutDigits, Saig_ManPoNum(p->pAig) );
+ if ( p->pPars->nFailOuts == Saig_ManPoNum(p->pAig) )
+ return 0; // all SAT
+ Pdr_QueueClean( p );
+ pCube = NULL;
+ break; // keep solving
+ }
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 0, Abc_Clock() - clkStart );
+ }
+ }
+ if ( fRefined )
+ break;
+ if ( p->pTime4Outs )
+ {
+ abctime timeSince = Abc_Clock() - clkOne;
+ assert( p->pTime4Outs[p->iOutCur] > 0 );
+ p->pTime4Outs[p->iOutCur] = (p->pTime4Outs[p->iOutCur] > timeSince) ? p->pTime4Outs[p->iOutCur] - timeSince : 0;
+ if ( p->pTime4Outs[p->iOutCur] == 0 && Vec_PtrEntry(p->vCexes, p->iOutCur) == NULL ) // undecided
+ {
+ p->pPars->nDropOuts++;
+ if ( p->pPars->vOutMap )
+ Vec_IntWriteEntry( p->pPars->vOutMap, p->iOutCur, -1 );
+ if ( !p->pPars->fNotVerbose )
+ Abc_Print( 1, "Timing out on output %*d in frame %d.\n", nOutDigits, p->iOutCur, iFrame );
+ }
+ p->timeToStopOne = 0;
+ }
+ }
+ if ( p->pPars->fUseAbs && p->vAbsFlops && !fRefined )
+ {
+ int i, Used;
+ Vec_IntForEachEntry( p->vAbsFlops, Used, i )
+ if ( Used && (Vec_IntEntry(p->vPrio, i) >> p->nPrioShift) == 0 )
+ Vec_IntWriteEntry( p->vAbsFlops, i, 0 );
+ }
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, !fRefined, Abc_Clock() - clkStart );
+ if ( fRefined )
+ continue;
+ //if ( p->pPars->fUseAbs && p->vAbsFlops )
+ // printf( "Finished frame %d with %d (%d) flops.\n", iFrame, Vec_IntCountPositive(p->vAbsFlops), Vec_IntCountPositive(p->vPrio) );
+ // open a new timeframe
+ p->nQueLim = p->pPars->nRestLimit;
+ assert( pCube == NULL );
+ Pdr_ManSetPropertyOutput( p, iFrame );
+ Pdr_ManCreateSolver( p, ++iFrame );
+ if ( fPrintClauses )
+ {
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
+ Pdr_ManPrintClauses( p, 0 );
+ }
+ // push clauses into this timeframe
+ RetValue = Pdr_ManPushClauses( p );
+ if ( RetValue == -1 )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ {
+ if ( p->timeToStop && Abc_Clock() > p->timeToStop )
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
+ else
+ Abc_Print( 1, "Reached conflict limit (%d) in frame.\n", p->pPars->nConfLimit, iFrame );
+ }
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( RetValue )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Pdr_ManReportInvariant( p );
+ if ( !p->pPars->fSilent )
+ Pdr_ManVerifyInvariant( p );
+ p->pPars->iFrame = iFrame;
+ // count the number of UNSAT outputs
+ p->pPars->nProveOuts = Saig_ManPoNum(p->pAig) - p->pPars->nFailOuts - p->pPars->nDropOuts;
+ // convert previously 'unknown' into 'unsat'
+ if ( p->pPars->vOutMap )
+ for ( iFrame = 0; iFrame < Saig_ManPoNum(p->pAig); iFrame++ )
+ if ( Vec_IntEntry(p->pPars->vOutMap, iFrame) == -2 ) // unknown
+ {
+ Vec_IntWriteEntry( p->pPars->vOutMap, iFrame, 1 ); // unsat
+ if ( p->pPars->fUseBridge )
+ Gia_ManToBridgeResult( stdout, 1, NULL, iFrame );
+ }
+ if ( p->pPars->nProveOuts == Saig_ManPoNum(p->pAig) )
+ return 1; // UNSAT
+ if ( p->pPars->nFailOuts > 0 )
+ return 0; // SAT
+ return -1;
+ }
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 0, Abc_Clock() - clkStart );
+
+ // check termination
+ if ( p->pPars->pFuncStop && p->pPars->pFuncStop(p->pPars->RunId) )
+ {
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( p->timeToStop && Abc_Clock() > p->timeToStop )
+ {
+ if ( fPrintClauses )
+ {
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
+ Pdr_ManPrintClauses( p, 0 );
+ }
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Abc_Print( 1, "Reached timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOut, iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( p->pPars->nTimeOutGap && p->pPars->timeLastSolved && Abc_Clock() > p->pPars->timeLastSolved + p->pPars->nTimeOutGap * CLOCKS_PER_SEC )
+ {
+ if ( fPrintClauses )
+ {
+ Abc_Print( 1, "*** Clauses after frame %d:\n", iFrame );
+ Pdr_ManPrintClauses( p, 0 );
+ }
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Abc_Print( 1, "Reached gap timeout (%d seconds) in frame %d.\n", p->pPars->nTimeOutGap, iFrame );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ if ( p->pPars->nFrameMax && iFrame >= p->pPars->nFrameMax )
+ {
+ if ( p->pPars->fVerbose )
+ Pdr_ManPrintProgress( p, 1, Abc_Clock() - clkStart );
+ if ( !p->pPars->fSilent )
+ Abc_Print( 1, "Reached limit on the number of timeframes (%d).\n", p->pPars->nFrameMax );
+ p->pPars->iFrame = iFrame;
+ return -1;
+ }
+ }
+ assert( 0 );
+ return -1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int IPdr_ManSolve( Aig_Man_t * pAig, Pdr_Par_t * pPars )
+{
+ Pdr_Man_t * p;
+ int k, RetValue;
+ Vec_Vec_t * vClausesSaved;
+
+ abctime clk = Abc_Clock();
+ if ( pPars->nTimeOutOne && !pPars->fSolveAll )
+ pPars->nTimeOutOne = 0;
+ if ( pPars->nTimeOutOne && pPars->nTimeOut == 0 )
+ pPars->nTimeOut = pPars->nTimeOutOne * Saig_ManPoNum(pAig) / 1000 + (int)((pPars->nTimeOutOne * Saig_ManPoNum(pAig) % 1000) > 0);
+ if ( pPars->fVerbose )
+ {
+// Abc_Print( 1, "Running PDR by Niklas Een (aka IC3 by Aaron Bradley) with these parameters:\n" );
+ Abc_Print( 1, "VarMax = %d. FrameMax = %d. QueMax = %d. TimeMax = %d. ",
+ pPars->nRecycle,
+ pPars->nFrameMax,
+ pPars->nRestLimit,
+ pPars->nTimeOut );
+ Abc_Print( 1, "MonoCNF = %s. SkipGen = %s. SolveAll = %s.\n",
+ pPars->fMonoCnf ? "yes" : "no",
+ pPars->fSkipGeneral ? "yes" : "no",
+ pPars->fSolveAll ? "yes" : "no" );
+ }
+ ABC_FREE( pAig->pSeqModel );
+
+
+ p = Pdr_ManStart( pAig, pPars, NULL );
+ while ( 1 ) {
+ RetValue = IPdr_ManSolveInt( p, 1, 0 );
+
+ if ( RetValue == -1 && pPars->iFrame == pPars->nFrameMax) {
+ vClausesSaved = IPdr_ManSaveClauses( p, 1 );
+
+ Pdr_ManStop( p );
+
+ p = Pdr_ManStart( pAig, pPars, NULL );
+ IPdr_ManRestore( p, vClausesSaved, NULL );
+
+ pPars->nFrameMax = pPars->nFrameMax << 1;
+
+ continue;
+ }
+
+ if ( RetValue == 0 )
+ assert( pAig->pSeqModel != NULL || p->vCexes != NULL );
+ if ( p->vCexes )
+ {
+ assert( p->pAig->vSeqModelVec == NULL );
+ p->pAig->vSeqModelVec = p->vCexes;
+ p->vCexes = NULL;
+ }
+ if ( p->pPars->fDumpInv )
+ {
+ char * pFileName = Extra_FileNameGenericAppend(p->pAig->pName, "_inv.pla");
+ Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) );
+ Pdr_ManDumpClauses( p, pFileName, RetValue==1 );
+ }
+ else if ( RetValue == 1 )
+ Abc_FrameSetInv( Pdr_ManDeriveInfinityClauses( p, RetValue!=1 ) );
+
+ p->tTotal += Abc_Clock() - clk;
+ Pdr_ManStop( p );
+
+ break;
+ }
+
+
+ pPars->iFrame--;
+ // convert all -2 (unknown) entries into -1 (undec)
+ if ( pPars->vOutMap )
+ for ( k = 0; k < Saig_ManPoNum(pAig); k++ )
+ if ( Vec_IntEntry(pPars->vOutMap, k) == -2 ) // unknown
+ Vec_IntWriteEntry( pPars->vOutMap, k, -1 ); // undec
+ if ( pPars->fUseBridge )
+ Gia_ManToBridgeAbort( stdout, 7, (unsigned char *)"timeout" );
+ return RetValue;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkDarIPdr ( Abc_Ntk_t * pNtk, Pdr_Par_t * pPars )
+{
+ int RetValue = -1;
+ abctime clk = Abc_Clock();
+ Aig_Man_t * pMan;
+ pMan = Abc_NtkToDar( pNtk, 0, 1 );
+
+ RetValue = IPdr_ManSolve( pMan, pPars );
+
+ if ( RetValue == 1 )
+ Abc_Print( 1, "Property proved. " );
+ else
+ {
+ if ( RetValue == 0 )
+ {
+ if ( pMan->pSeqModel == NULL )
+ Abc_Print( 1, "Counter-example is not available.\n" );
+ else
+ {
+ Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. ", pMan->pSeqModel->iPo, pNtk->pName, pMan->pSeqModel->iFrame );
+ if ( !Saig_ManVerifyCex( pMan, pMan->pSeqModel ) )
+ Abc_Print( 1, "Counter-example verification has FAILED.\n" );
+ }
+ }
+ else if ( RetValue == -1 )
+ Abc_Print( 1, "Property UNDECIDED. " );
+ else
+ assert( 0 );
+ }
+ ABC_PRT( "Time", Abc_Clock() - clk );
+
+
+ ABC_FREE( pNtk->pSeqModel );
+ pNtk->pSeqModel = pMan->pSeqModel;
+ pMan->pSeqModel = NULL;
+ if ( pNtk->vSeqModelVec )
+ Vec_PtrFreeFree( pNtk->vSeqModelVec );
+ pNtk->vSeqModelVec = pMan->vSeqModelVec;
+ pMan->vSeqModelVec = NULL;
+ Aig_ManStop( pMan );
+ return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/proof/pdr/pdrInt.h b/src/proof/pdr/pdrInt.h
index 6a08a150..e5b04339 100644
--- a/src/proof/pdr/pdrInt.h
+++ b/src/proof/pdr/pdrInt.h
@@ -30,6 +30,8 @@
#include "sat/cnf/cnf.h"
#include "sat/bsat/satSolver.h"
#include "pdr.h"
+#include "misc/hash/hashInt.h"
+#include "aig/gia/giaAig.h"
ABC_NAMESPACE_HEADER_START
@@ -41,6 +43,8 @@ ABC_NAMESPACE_HEADER_START
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
+typedef struct Txs_Man_t_ Txs_Man_t;
+
typedef struct Pdr_Set_t_ Pdr_Set_t;
struct Pdr_Set_t_
{
@@ -68,6 +72,7 @@ struct Pdr_Man_t_
// input problem
Pdr_Par_t * pPars; // parameters
Aig_Man_t * pAig; // user's AIG
+ Gia_Man_t * pGia; // user's AIG
// static CNF representation
Cnf_Man_t * pCnfMan; // CNF manager
Cnf_Dat_t * pCnf1; // CNF for this AIG
@@ -79,6 +84,7 @@ struct Pdr_Man_t_
Vec_Wec_t * vVLits; // CNF literals
// data representation
int iOutCur; // current output
+ int nPrioShift;// priority shift
Vec_Ptr_t * vCexes; // counter-examples for each output
Vec_Ptr_t * vSolvers; // SAT solvers
Vec_Vec_t * vClauses; // clauses by timeframe
@@ -86,6 +92,14 @@ struct Pdr_Man_t_
int * pOrder; // ordering of the lits
Vec_Int_t * vActVars; // the counter of activation variables
int iUseFrame; // the first used frame
+ int nAbsFlops; // the number of flops used
+ Vec_Int_t * vAbsFlops; // flops currently used
+ Vec_Int_t * vMapFf2Ppi;
+ Vec_Int_t * vMapPpi2Ff;
+ int nCexes;
+ int nCexesTotal;
+ // terminary simulation
+ Txs_Man_t * pTxs;
// internal use
Vec_Int_t * vPrio; // priority flops
Vec_Int_t * vLits; // array of literals
@@ -98,8 +112,6 @@ struct Pdr_Man_t_
Vec_Int_t * vVisits; // intermediate
Vec_Int_t * vCi2Rem; // CIs to be removed
Vec_Int_t * vRes; // final result
- Vec_Int_t * vSuppLits; // support literals
- Pdr_Set_t * pCubeJust; // justification
abctime * pTime4Outs;// timeout per output
Vec_Ptr_t * vInfCubes; // infinity clauses/cubes
// statistics
@@ -118,6 +130,8 @@ struct Pdr_Man_t_
int nQueCur;
int nQueMax;
int nQueLim;
+ int nXsimRuns;
+ int nXsimLits;
// runtime
abctime timeToStop;
abctime timeToStopOne;
@@ -130,6 +144,7 @@ struct Pdr_Man_t_
abctime tTsim;
abctime tContain;
abctime tCnf;
+ abctime tAbs;
abctime tTotal;
};
@@ -154,8 +169,6 @@ static inline abctime Pdr_ManTimeLimit( Pdr_Man_t * p )
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-/*=== pdrCex.c ==========================================================*/
-extern Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p );
/*=== pdrCnf.c ==========================================================*/
extern int Pdr_ObjSatVar( Pdr_Man_t * p, int k, int Pol, Aig_Obj_t * pObj );
extern int Pdr_ObjRegNum( Pdr_Man_t * p, int k, int iSatVar );
@@ -176,6 +189,7 @@ extern Vec_Int_t * Pdr_ManDeriveInfinityClauses( Pdr_Man_t * p, int fReduce
extern Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrioInit );
extern void Pdr_ManStop( Pdr_Man_t * p );
extern Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p );
+extern Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p );
/*=== pdrSat.c ==========================================================*/
extern sat_solver * Pdr_ManCreateSolver( Pdr_Man_t * p, int k );
extern sat_solver * Pdr_ManFetchSolver( Pdr_Man_t * p, int k );
@@ -185,9 +199,13 @@ extern Vec_Int_t * Pdr_ManLitsToCube( Pdr_Man_t * p, int k, int * pArray, in
extern void Pdr_ManSolverAddClause( Pdr_Man_t * p, int k, Pdr_Set_t * pCube );
extern void Pdr_ManCollectValues( Pdr_Man_t * p, int k, Vec_Int_t * vObjIds, Vec_Int_t * vValues );
extern int Pdr_ManCheckCubeCs( Pdr_Man_t * p, int k, Pdr_Set_t * pCube );
-extern int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf );
+extern int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf, int fUseLit );
/*=== pdrTsim.c ==========================================================*/
extern Pdr_Set_t * Pdr_ManTernarySim( Pdr_Man_t * p, int k, Pdr_Set_t * pCube );
+/*=== pdrTsim2.c ==========================================================*/
+extern Txs_Man_t * Txs_ManStart( Pdr_Man_t * pMan, Aig_Man_t * pAig, Vec_Int_t * vPrio );
+extern void Txs_ManStop( Txs_Man_t * );
+extern Pdr_Set_t * Txs_ManTernarySim( Txs_Man_t * p, int k, Pdr_Set_t * pCube );
/*=== pdrUtil.c ==========================================================*/
extern Pdr_Set_t * Pdr_SetAlloc( int nSize );
extern Pdr_Set_t * Pdr_SetCreate( Vec_Int_t * vLits, Vec_Int_t * vPiLits );
@@ -196,10 +214,13 @@ extern Pdr_Set_t * Pdr_SetCreateSubset( Pdr_Set_t * pSet, int * pLits, int n
extern Pdr_Set_t * Pdr_SetDup( Pdr_Set_t * pSet );
extern Pdr_Set_t * Pdr_SetRef( Pdr_Set_t * p );
extern void Pdr_SetDeref( Pdr_Set_t * p );
+extern Pdr_Set_t * ZPdr_SetIntersection( Pdr_Set_t * p1, Pdr_Set_t * p2, Hash_Int_t * keep );
extern int Pdr_SetContains( Pdr_Set_t * pOld, Pdr_Set_t * pNew );
extern int Pdr_SetContainsSimple( Pdr_Set_t * pOld, Pdr_Set_t * pNew );
extern int Pdr_SetIsInit( Pdr_Set_t * p, int iRemove );
+extern int ZPdr_SetIsInit( Pdr_Set_t * p );
extern void Pdr_SetPrint( FILE * pFile, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCounts );
+extern void ZPdr_SetPrint( Pdr_Set_t * p );
extern void Pdr_SetPrintStr( Vec_Str_t * vStr, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCounts );
extern int Pdr_SetCompare( Pdr_Set_t ** pp1, Pdr_Set_t ** pp2 );
extern Pdr_Obl_t * Pdr_OblStart( int k, int prio, Pdr_Set_t * pState, Pdr_Obl_t * pNext );
@@ -212,7 +233,6 @@ extern void Pdr_QueueClean( Pdr_Man_t * p );
extern void Pdr_QueuePush( Pdr_Man_t * p, Pdr_Obl_t * pObl );
extern void Pdr_QueuePrint( Pdr_Man_t * p );
extern void Pdr_QueueStop( Pdr_Man_t * p );
-extern int Pdr_ManCubeJust( Pdr_Man_t * p, int k, Pdr_Set_t * pCube );
ABC_NAMESPACE_HEADER_END
diff --git a/src/proof/pdr/pdrInv.c b/src/proof/pdr/pdrInv.c
index 02b90a36..baade033 100644
--- a/src/proof/pdr/pdrInv.c
+++ b/src/proof/pdr/pdrInv.c
@@ -50,7 +50,16 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time )
Vec_Ptr_t * vVec;
int i, ThisSize, Length, LengthStart;
if ( Vec_PtrSize(p->vSolvers) < 2 )
+ {
+ printf( "Frame " );
+ printf( "Clauses " );
+ printf( "Max Queue " );
+ printf( "Flops " );
+ printf( "Cex " );
+ printf( "Time" );
+ printf( "\n" );
return;
+ }
if ( Abc_FrameIsBatchMode() && !fClose )
return;
// count the total length of the printout
@@ -80,7 +89,10 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time )
}
for ( i = ThisSize; i < 70; i++ )
Abc_Print( 1, " " );
- Abc_Print( 1, "%6d", p->nQueMax );
+ Abc_Print( 1, "%5d", p->nQueMax );
+ Abc_Print( 1, "%6d", p->vAbsFlops ? Vec_IntCountPositive(p->vAbsFlops) : p->nAbsFlops );
+ if ( p->pPars->fUseAbs )
+ Abc_Print( 1, "%4d", p->nCexes );
Abc_Print( 1, "%10.2f sec", 1.0*Time/CLOCKS_PER_SEC );
if ( p->pPars->fSolveAll )
Abc_Print( 1, " CEX =%4d", p->pPars->nFailOuts );
@@ -88,7 +100,7 @@ void Pdr_ManPrintProgress( Pdr_Man_t * p, int fClose, abctime Time )
Abc_Print( 1, " T/O =%3d", p->pPars->nDropOuts );
Abc_Print( 1, "%s", fClose ? "\n":"\r" );
if ( fClose )
- p->nQueMax = 0;
+ p->nQueMax = 0, p->nCexes = 0;
fflush( stdout );
}
@@ -467,8 +479,10 @@ void Pdr_ManReportInvariant( Pdr_Man_t * p )
Vec_Ptr_t * vCubes;
int kStart = Pdr_ManFindInvariantStart( p );
vCubes = Pdr_ManCollectCubes( p, kStart );
- Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d)\n",
- kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig) );
+ Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d) (cex = %d, ave = %.2f)\n",
+ kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig), p->nCexesTotal, 1.0*p->nXsimLits/p->nXsimRuns );
+// Abc_Print( 1, "Invariant F[%d] : %d clauses with %d flops (out of %d)\n",
+// kStart, Vec_PtrSize(vCubes), Pdr_ManCountVariables(p, kStart), Aig_ManRegNum(p->pAig) );
Vec_PtrFree( vCubes );
}
@@ -605,9 +619,363 @@ Vec_Int_t * Pdr_ManDeriveInfinityClauses( Pdr_Man_t * p, int fReduce )
//Vec_PtrFree( vCubes );
Vec_PtrFreeP( &p->vInfCubes );
p->vInfCubes = vCubes;
+ Vec_IntPush( vResult, Aig_ManRegNum(p->pAig) );
return vResult;
}
+
+
+/**Function*************************************************************
+
+ Synopsis [Remove clauses while maintaining the invariant.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+#define Pdr_ForEachCube( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += pCut[0] + 1 )
+
+Vec_Int_t * Pdr_InvMap( Vec_Int_t * vCounts )
+{
+ int i, k = 0, Count;
+ Vec_Int_t * vMap = Vec_IntStart( Vec_IntSize(vCounts) );
+ Vec_IntForEachEntry( vCounts, Count, i )
+ if ( Count )
+ Vec_IntWriteEntry( vMap, i, k++ );
+ return vMap;
+}
+Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv )
+{
+ int i, k, * pCube, * pList = Vec_IntArray(vInv);
+ Vec_Int_t * vCounts = Vec_IntStart( Vec_IntEntryLast(vInv) );
+ Pdr_ForEachCube( pList, pCube, i )
+ for ( k = 0; k < pCube[0]; k++ )
+ Vec_IntAddToEntry( vCounts, Abc_Lit2Var(pCube[k+1]), 1 );
+ return vCounts;
+}
+int Pdr_InvUsedFlopNum( Vec_Int_t * vInv )
+{
+ Vec_Int_t * vCounts = Pdr_InvCounts( vInv );
+ int nZeros = Vec_IntCountZero( vCounts );
+ Vec_IntFree( vCounts );
+ return Vec_IntEntryLast(vInv) - nZeros;
+}
+
+Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts )
+{
+ Vec_Str_t * vStr = Vec_StrAlloc( 1000 );
+ Vec_Int_t * vMap = Pdr_InvMap( vCounts );
+ int nVars = Vec_IntSize(vCounts) - Vec_IntCountZero(vCounts);
+ int i, k, * pCube, * pList = Vec_IntArray(vInv);
+ char * pBuffer = ABC_ALLOC( char, nVars );
+ for ( i = 0; i < nVars; i++ )
+ pBuffer[i] = '-';
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ for ( k = 0; k < pCube[0]; k++ )
+ pBuffer[Vec_IntEntry(vMap, Abc_Lit2Var(pCube[k+1]))] = '0' + !Abc_LitIsCompl(pCube[k+1]);
+ for ( k = 0; k < nVars; k++ )
+ Vec_StrPush( vStr, pBuffer[k] );
+ Vec_StrPush( vStr, ' ' );
+ Vec_StrPush( vStr, '1' );
+ Vec_StrPush( vStr, '\n' );
+ for ( k = 0; k < pCube[0]; k++ )
+ pBuffer[Vec_IntEntry(vMap, Abc_Lit2Var(pCube[k+1]))] = '-';
+ }
+ Vec_StrPush( vStr, '\0' );
+ ABC_FREE( pBuffer );
+ Vec_IntFree( vMap );
+ return vStr;
+}
+void Pdr_InvPrint( Vec_Int_t * vInv, int fVerbose )
+{
+ printf( "Invariant contains %d clauses with %d literals and %d flops (out of %d).\n", Vec_IntEntry(vInv, 0), Vec_IntSize(vInv)-Vec_IntEntry(vInv, 0)-2, Pdr_InvUsedFlopNum(vInv), Vec_IntEntryLast(vInv) );
+ if ( fVerbose )
+ {
+ Vec_Int_t * vCounts = Pdr_InvCounts( vInv );
+ Vec_Str_t * vStr = Pdr_InvPrintStr( vInv, vCounts );
+ printf( "%s", Vec_StrArray( vStr ) );
+ Vec_IntFree( vCounts );
+ Vec_StrFree( vStr );
+ }
+}
+
+int Pdr_InvCheck_int( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose, sat_solver * pSat, int fSkip )
+{
+ int nBTLimit = 0;
+ int fCheckProperty = 1;
+ int i, k, status, nFailed = 0, nFailedOuts = 0;
+ // collect cubes
+ int * pCube, * pList = Vec_IntArray(vInv);
+ // create variables
+ Vec_Int_t * vLits = Vec_IntAlloc(100);
+ int iFoVarBeg = sat_solver_nvars(pSat) - Gia_ManRegNum(p);
+ int iFiVarBeg = 1 + Gia_ManPoNum(p);
+ // add cubes
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ // collect literals
+ Vec_IntClear( vLits );
+ for ( k = 0; k < pCube[0]; k++ )
+ if ( pCube[k+1] != -1 )
+ Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) );
+ if ( Vec_IntSize(vLits) == 0 )
+ {
+ Vec_IntFree( vLits );
+ return 1;
+ }
+ // add it to the solver
+ status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) );
+ assert( status == 1 );
+ }
+ // verify property output
+ if ( fCheckProperty )
+ {
+ for ( i = 0; i < Gia_ManPoNum(p); i++ )
+ {
+ Vec_IntFill( vLits, 1, Abc_Var2Lit(1+i, 0) );
+ status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 );
+ if ( status == l_Undef ) // timeout
+ break;
+ if ( status == l_True ) // sat - property fails
+ {
+ if ( fVerbose )
+ printf( "Coverage check failed for output %d.\n", i );
+ nFailedOuts++;
+ if ( fSkip )
+ {
+ Vec_IntFree( vLits );
+ return 1;
+ }
+ continue;
+ }
+ assert( status == l_False ); // unsat - property holds
+ }
+ }
+ // iterate through cubes in the direct order
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ // collect cube
+ Vec_IntClear( vLits );
+ for ( k = 0; k < pCube[0]; k++ )
+ if ( pCube[k+1] != -1 )
+ Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) );
+ // check if this cube intersects with the complement of other cubes in the solver
+ // if it does not intersect, then it is redundant and can be skipped
+ status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 );
+ if ( status != l_True && fVerbose )
+ printf( "Finished checking clause %d (out of %d)...\r", i, pList[0] );
+ if ( status == l_Undef ) // timeout
+ break;
+ if ( status == l_False ) // unsat -- correct
+ continue;
+ assert( status == l_True );
+ if ( fVerbose )
+ printf( "Inductiveness check failed for clause %d.\n", i );
+ nFailed++;
+ if ( fSkip )
+ {
+ Vec_IntFree( vLits );
+ return 1;
+ }
+ }
+ Vec_IntFree( vLits );
+ return nFailed + nFailedOuts;
+}
+
+int Pdr_InvCheck( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose )
+{
+ int RetValue;
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
+ sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ assert( sat_solver_nvars(pSat) == pCnf->nVars );
+ Cnf_DataFree( pCnf );
+ RetValue = Pdr_InvCheck_int( p, vInv, fVerbose, pSat, 0 );
+ sat_solver_delete( pSat );
+ return RetValue;
+}
+
+Vec_Int_t * Pdr_InvMinimize( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose )
+{
+ int nBTLimit = 0;
+ int fCheckProperty = 1;
+ abctime clk = Abc_Clock();
+ int n, i, k, status, nLits, fFailed = 0, fCannot = 0, nRemoved = 0;
+ Vec_Int_t * vRes = NULL;
+ // create SAT solver
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
+ sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ int * pCube, * pList = Vec_IntArray(vInv), nCubes = pList[0];
+ // create variables
+ Vec_Int_t * vLits = Vec_IntAlloc(100);
+ Vec_Bit_t * vRemoved = Vec_BitStart( nCubes );
+ int iFoVarBeg = pCnf->nVars - Gia_ManRegNum(p);
+ int iFiVarBeg = 1 + Gia_ManPoNum(p);
+ int iAuxVarBeg = sat_solver_nvars(pSat);
+ // allocate auxiliary variables
+ assert( sat_solver_nvars(pSat) == pCnf->nVars );
+ sat_solver_setnvars( pSat, sat_solver_nvars(pSat) + nCubes );
+ // add clauses
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ // collect literals
+ Vec_IntFill( vLits, 1, Abc_Var2Lit(iAuxVarBeg + i, 1) ); // neg aux literal
+ for ( k = 0; k < pCube[0]; k++ )
+ Vec_IntPush( vLits, Abc_Var2Lit(iFoVarBeg + Abc_Lit2Var(pCube[k+1]), !Abc_LitIsCompl(pCube[k+1])) );
+ // add it to the solver
+ status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) );
+ assert( status == 1 );
+ }
+ // iterate through clauses
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ if ( Vec_BitEntry(vRemoved, i) )
+ continue;
+ // collect aux literals for remaining clauses
+ Vec_IntClear( vLits );
+ for ( k = 0; k < nCubes; k++ )
+ if ( k != i && !Vec_BitEntry(vRemoved, k) ) // skip this cube and already removed cubes
+ Vec_IntPush( vLits, Abc_Var2Lit(iAuxVarBeg + k, 0) ); // pos aux literal
+ nLits = Vec_IntSize( vLits );
+ // check if the property still holds
+ if ( fCheckProperty )
+ {
+ for ( k = 0; k < Gia_ManPoNum(p); k++ )
+ {
+ Vec_IntShrink( vLits, nLits );
+ Vec_IntPush( vLits, Abc_Var2Lit(1+k, 0) );
+ status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 );
+ if ( status == l_Undef ) // timeout
+ {
+ fFailed = 1;
+ break;
+ }
+ if ( status == l_True ) // sat - property fails
+ break;
+ assert( status == l_False ); // unsat - property holds
+ }
+ if ( fFailed )
+ break;
+ if ( k < Gia_ManPoNum(p) )
+ continue;
+ }
+ // check other clauses
+ fCannot = 0;
+ Pdr_ForEachCube( pList, pCube, n )
+ {
+ if ( Vec_BitEntry(vRemoved, n) || n == i )
+ continue;
+ // collect cube
+ Vec_IntShrink( vLits, nLits );
+ for ( k = 0; k < pCube[0]; k++ )
+ Vec_IntPush( vLits, Abc_Var2Lit(iFiVarBeg + Abc_Lit2Var(pCube[k+1]), Abc_LitIsCompl(pCube[k+1])) );
+ // check if this cube intersects with the complement of other cubes in the solver
+ // if it does not intersect, then it is redundant and can be skipped
+ status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), nBTLimit, 0, 0, 0 );
+ if ( status == l_Undef ) // timeout
+ {
+ fFailed = 1;
+ break;
+ }
+ if ( status == l_False ) // unsat -- correct
+ continue;
+ assert( status == l_True );
+ // cannot remove
+ fCannot = 1;
+ break;
+ }
+ if ( fFailed )
+ break;
+ if ( fCannot )
+ continue;
+ if ( fVerbose )
+ printf( "Removing clause %d.\n", i );
+ Vec_BitWriteEntry( vRemoved, i, 1 );
+ nRemoved++;
+ }
+ if ( nRemoved )
+ printf( "Invariant minimization reduced %d clauses (out of %d). ", nRemoved, nCubes );
+ else
+ printf( "Invariant minimization did not change the invariant. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ // cleanup cover
+ if ( !fFailed && nRemoved > 0 ) // finished without timeout and removed some cubes
+ {
+ vRes = Vec_IntAlloc( 1000 );
+ Vec_IntPush( vRes, nCubes-nRemoved );
+ Pdr_ForEachCube( pList, pCube, i )
+ if ( !Vec_BitEntry(vRemoved, i) )
+ for ( k = 0; k <= pCube[0]; k++ )
+ Vec_IntPush( vRes, pCube[k] );
+ Vec_IntPush( vRes, Vec_IntEntryLast(vInv) );
+ }
+ Cnf_DataFree( pCnf );
+ sat_solver_delete( pSat );
+ Vec_BitFree( vRemoved );
+ Vec_IntFree( vLits );
+ return vRes;
+}
+
+Vec_Int_t * Pdr_InvMinimizeLits( Gia_Man_t * p, Vec_Int_t * vInv, int fVerbose )
+{
+ Vec_Int_t * vRes = NULL;
+ abctime clk = Abc_Clock();
+ int i, k, nLits = 0, * pCube, * pList = Vec_IntArray(vInv), nRemoved = 0;
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
+ sat_solver * pSat;
+// sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ nLits += pCube[0];
+ for ( k = 0; k < pCube[0]; k++ )
+ {
+ int Save = pCube[k+1];
+ pCube[k+1] = -1;
+ //sat_solver_bookmark( pSat );
+ pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ if ( Pdr_InvCheck_int(p, vInv, 0, pSat, 1) )
+ pCube[k+1] = Save;
+ else
+ {
+ if ( fVerbose )
+ printf( "Removing lit %d from clause %d.\n", k, i );
+ nRemoved++;
+ }
+ sat_solver_delete( pSat );
+ //sat_solver_rollback( pSat );
+ //sat_solver_bookmark( pSat );
+ }
+ }
+ Cnf_DataFree( pCnf );
+ //sat_solver_delete( pSat );
+ if ( nRemoved )
+ printf( "Invariant minimization reduced %d literals (out of %d). ", nRemoved, nLits );
+ else
+ printf( "Invariant minimization did not change the invariant. " );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ if ( nRemoved > 0 ) // finished without timeout and removed some lits
+ {
+ vRes = Vec_IntAlloc( 1000 );
+ Vec_IntPush( vRes, pList[0] );
+ Pdr_ForEachCube( pList, pCube, i )
+ {
+ int nLits = 0;
+ for ( k = 0; k < pCube[0]; k++ )
+ if ( pCube[k+1] != -1 )
+ nLits++;
+ Vec_IntPush( vRes, nLits );
+ for ( k = 0; k < pCube[0]; k++ )
+ if ( pCube[k+1] != -1 )
+ Vec_IntPush( vRes, pCube[k+1] );
+ }
+ Vec_IntPush( vRes, Vec_IntEntryLast(vInv) );
+ }
+ return vRes;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/pdr/pdrMan.c b/src/proof/pdr/pdrMan.c
index b58c479b..a076223b 100644
--- a/src/proof/pdr/pdrMan.c
+++ b/src/proof/pdr/pdrMan.c
@@ -19,6 +19,7 @@
***********************************************************************/
#include "pdrInt.h"
+#include "sat/bmc/bmc.h"
ABC_NAMESPACE_IMPL_START
@@ -33,6 +34,208 @@ ABC_NAMESPACE_IMPL_START
/**Function*************************************************************
+ Synopsis [Structural analysis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Pdr_ManDeriveFlopPriorities3( Gia_Man_t * p, int fMuxCtrls )
+{
+ int fDiscount = 0;
+ Vec_Wec_t * vLevels;
+ Vec_Int_t * vRes, * vLevel, * vCosts;
+ Gia_Obj_t * pObj, * pCtrl, * pData0, * pData1;
+ int i, k, Entry, MaxEntry = 0;
+ Gia_ManCreateRefs(p);
+ // discount references
+ if ( fDiscount )
+ {
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0));
+ pData0 = Gia_Regular(pData0);
+ pData1 = Gia_Regular(pData1);
+ p->pRefs[Gia_ObjId(p, pCtrl)]--;
+ if ( pData0 == pData1 )
+ p->pRefs[Gia_ObjId(p, pData0)]--;
+ }
+ }
+ // create flop costs
+ vCosts = Vec_IntAlloc( Gia_ManRegNum(p) );
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ Vec_IntPush( vCosts, Gia_ObjRefNum(p, pObj) );
+ MaxEntry = Abc_MaxInt( MaxEntry, Gia_ObjRefNum(p, pObj) );
+ //printf( "%d(%d) ", i, Gia_ObjRefNum(p, pObj) );
+ }
+ //printf( "\n" );
+ MaxEntry++;
+ // add costs due to MUX inputs
+ if ( fMuxCtrls )
+ {
+ int fVerbose = 0;
+ Vec_Bit_t * vCtrls = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vDatas = Vec_BitStart( Gia_ManObjNum(p) );
+ Gia_Obj_t * pCtrl, * pData1, * pData0;
+ int nCtrls = 0, nDatas = 0, nBoth = 0;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ pCtrl = Gia_ObjRecognizeMux( pObj, &pData1, &pData0 );
+ pCtrl = Gia_Regular(pCtrl);
+ pData1 = Gia_Regular(pData1);
+ pData0 = Gia_Regular(pData0);
+ Vec_BitWriteEntry( vCtrls, Gia_ObjId(p, pCtrl), 1 );
+ Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData1), 1 );
+ Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData0), 1 );
+ }
+ Gia_ManForEachRo( p, pObj, i )
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) )
+ Vec_IntAddToEntry( vCosts, i, MaxEntry );
+ //else if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ // Vec_IntAddToEntry( vCosts, i, MaxEntry );
+ MaxEntry = 2*MaxEntry + 1;
+ // print out
+ if ( fVerbose )
+ {
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) )
+ nCtrls++;
+ if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ nDatas++;
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) && Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ nBoth++;
+ }
+ printf( "%10s : Flops = %5d. Ctrls = %5d. Datas = %5d. Both = %5d.\n", Gia_ManName(p), Gia_ManRegNum(p), nCtrls, nDatas, nBoth );
+ }
+ Vec_BitFree( vCtrls );
+ Vec_BitFree( vDatas );
+ }
+ // create levelized structure
+ vLevels = Vec_WecStart( MaxEntry );
+ Vec_IntForEachEntry( vCosts, Entry, i )
+ Vec_WecPush( vLevels, Entry, i );
+ // collect in this order
+ MaxEntry = 0;
+ vRes = Vec_IntStart( Gia_ManRegNum(p) );
+ Vec_WecForEachLevel( vLevels, vLevel, i )
+ Vec_IntForEachEntry( vLevel, Entry, k )
+ Vec_IntWriteEntry( vRes, Entry, MaxEntry++ );
+ //printf( "%d ", Gia_ObjRefNum(p, Gia_ManCi(p, Gia_ManPiNum(p)+Entry)) );
+ //printf( "\n" );
+ assert( MaxEntry == Gia_ManRegNum(p) );
+ Vec_WecFree( vLevels );
+ Vec_IntFree( vCosts );
+ ABC_FREE( p->pRefs );
+//Vec_IntPrint( vRes );
+ return vRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Structural analysis.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Pdr_ManDeriveFlopPriorities2( Gia_Man_t * p, int fMuxCtrls )
+{
+ int fDiscount = 0;
+ Vec_Int_t * vRes = NULL;
+ Gia_Obj_t * pObj, * pCtrl, * pData0, * pData1;
+ int MaxEntry = 0;
+ int i, * pPerm;
+ // create flop costs
+ Vec_Int_t * vCosts = Vec_IntStart( Gia_ManRegNum(p) );
+ Gia_ManCreateRefs(p);
+ // discount references
+ if ( fDiscount )
+ {
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ pCtrl = Gia_Regular(Gia_ObjRecognizeMux(pObj, &pData1, &pData0));
+ pData0 = Gia_Regular(pData0);
+ pData1 = Gia_Regular(pData1);
+ p->pRefs[Gia_ObjId(p, pCtrl)]--;
+ if ( pData0 == pData1 )
+ p->pRefs[Gia_ObjId(p, pData0)]--;
+ }
+ }
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ Vec_IntWriteEntry( vCosts, i, Gia_ObjRefNum(p, pObj) );
+ MaxEntry = Abc_MaxInt( MaxEntry, Gia_ObjRefNum(p, pObj) );
+ }
+ MaxEntry++;
+ ABC_FREE( p->pRefs );
+ // add costs due to MUX inputs
+ if ( fMuxCtrls )
+ {
+ int fVerbose = 0;
+ Vec_Bit_t * vCtrls = Vec_BitStart( Gia_ManObjNum(p) );
+ Vec_Bit_t * vDatas = Vec_BitStart( Gia_ManObjNum(p) );
+ Gia_Obj_t * pCtrl, * pData1, * pData0;
+ int nCtrls = 0, nDatas = 0, nBoth = 0;
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjIsMuxType(pObj) )
+ continue;
+ pCtrl = Gia_ObjRecognizeMux( pObj, &pData1, &pData0 );
+ pCtrl = Gia_Regular(pCtrl);
+ pData1 = Gia_Regular(pData1);
+ pData0 = Gia_Regular(pData0);
+ Vec_BitWriteEntry( vCtrls, Gia_ObjId(p, pCtrl), 1 );
+ Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData1), 1 );
+ Vec_BitWriteEntry( vDatas, Gia_ObjId(p, pData0), 1 );
+ }
+ Gia_ManForEachRo( p, pObj, i )
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) )
+ Vec_IntAddToEntry( vCosts, i, MaxEntry );
+ //else if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ // Vec_IntAddToEntry( vCosts, i, MaxEntry );
+ // print out
+ if ( fVerbose )
+ {
+ Gia_ManForEachRo( p, pObj, i )
+ {
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) )
+ nCtrls++;
+ if ( Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ nDatas++;
+ if ( Vec_BitEntry(vCtrls, Gia_ObjId(p, pObj)) && Vec_BitEntry(vDatas, Gia_ObjId(p, pObj)) )
+ nBoth++;
+ }
+ printf( "%10s : Flops = %5d. Ctrls = %5d. Datas = %5d. Both = %5d.\n", Gia_ManName(p), Gia_ManRegNum(p), nCtrls, nDatas, nBoth );
+ }
+ Vec_BitFree( vCtrls );
+ Vec_BitFree( vDatas );
+ }
+ // create ordering based on costs
+ pPerm = Abc_MergeSortCost( Vec_IntArray(vCosts), Vec_IntSize(vCosts) );
+ vRes = Vec_IntAllocArray( pPerm, Vec_IntSize(vCosts) );
+ Vec_IntFree( vCosts );
+ vCosts = Vec_IntInvert( vRes, -1 );
+ Vec_IntFree( vRes );
+//Vec_IntPrint( vCosts );
+ return vCosts;
+}
+
+/**Function*************************************************************
+
Synopsis [Creates manager.]
Description []
@@ -48,6 +251,7 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio
p = ABC_CALLOC( Pdr_Man_t, 1 );
p->pPars = pPars;
p->pAig = pAig;
+ p->pGia = (pPars->fFlopPrio || p->pPars->fNewXSim || p->pPars->fUseAbs) ? Gia_ManFromAigSimple(pAig) : NULL;
p->vSolvers = Vec_PtrAlloc( 0 );
p->vClauses = Vec_VecAlloc( 0 );
p->pQueue = NULL;
@@ -56,7 +260,15 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio
if ( !p->pPars->fMonoCnf )
p->vVLits = Vec_WecStart( 1+Abc_MaxInt(1, Aig_ManLevels(pAig)) );
// internal use
- p->vPrio = vPrioInit ? vPrioInit : Vec_IntStart( Aig_ManRegNum(pAig) ); // priority flops
+ p->nPrioShift = Abc_Base2Log(Aig_ManRegNum(pAig));
+ if ( vPrioInit )
+ p->vPrio = vPrioInit;
+ else if ( pPars->fFlopPrio )
+ p->vPrio = Pdr_ManDeriveFlopPriorities2(p->pGia, 1);
+ else if ( p->pPars->fNewXSim )
+ p->vPrio = Vec_IntStartNatural( Aig_ManRegNum(pAig) );
+ else
+ p->vPrio = Vec_IntStart( Aig_ManRegNum(pAig) );
p->vLits = Vec_IntAlloc( 100 ); // array of literals
p->vCiObjs = Vec_IntAlloc( 100 ); // cone leaves
p->vCoObjs = Vec_IntAlloc( 100 ); // cone roots
@@ -67,9 +279,9 @@ Pdr_Man_t * Pdr_ManStart( Aig_Man_t * pAig, Pdr_Par_t * pPars, Vec_Int_t * vPrio
p->vVisits = Vec_IntAlloc( 100 ); // intermediate
p->vCi2Rem = Vec_IntAlloc( 100 ); // CIs to be removed
p->vRes = Vec_IntAlloc( 100 ); // final result
- p->vSuppLits= Vec_IntAlloc( 100 ); // support literals
- p->pCubeJust= Pdr_SetAlloc( Saig_ManRegNum(pAig) );
p->pCnfMan = Cnf_ManStart();
+ // ternary simulation
+ p->pTxs = pPars->fNewXSim ? Txs_ManStart( p, pAig, p->vPrio ) : NULL;
// additional AIG data-members
if ( pAig->pFanData == NULL )
Aig_ManFanoutStart( pAig );
@@ -108,11 +320,12 @@ void Pdr_ManStop( Pdr_Man_t * p )
Pdr_Set_t * pCla;
sat_solver * pSat;
int i, k;
+ Gia_ManStopP( &p->pGia );
Aig_ManCleanMarkAB( p->pAig );
if ( p->pPars->fVerbose )
{
- Abc_Print( 1, "Block =%5d Oblig =%6d Clause =%6d Call =%6d (sat=%.1f%%) Start =%4d\n",
- p->nBlocks, p->nObligs, p->nCubes, p->nCalls, 100.0 * p->nCallsS / p->nCalls, p->nStarts );
+ Abc_Print( 1, "Block =%5d Oblig =%6d Clause =%6d Call =%6d (sat=%.1f%%) Cex =%4d Start =%4d\n",
+ p->nBlocks, p->nObligs, p->nCubes, p->nCalls, 100.0 * p->nCallsS / p->nCalls, p->nCexesTotal, p->nStarts );
ABC_PRTP( "SAT solving", p->tSat, p->tTotal );
ABC_PRTP( " unsat ", p->tSatUnsat, p->tTotal );
ABC_PRTP( " sat ", p->tSatSat, p->tTotal );
@@ -121,6 +334,7 @@ void Pdr_ManStop( Pdr_Man_t * p )
ABC_PRTP( "Ternary sim", p->tTsim, p->tTotal );
ABC_PRTP( "Containment", p->tContain, p->tTotal );
ABC_PRTP( "CNF compute", p->tCnf, p->tTotal );
+ ABC_PRTP( "Refinement ", p->tAbs, p->tTotal );
ABC_PRTP( "TOTAL ", p->tTotal, p->tTotal );
fflush( stdout );
}
@@ -150,6 +364,12 @@ void Pdr_ManStop( Pdr_Man_t * p )
Vec_WecFreeP( &p->vVLits );
// CNF manager
Cnf_ManStop( p->pCnfMan );
+ Vec_IntFreeP( &p->vAbsFlops );
+ Vec_IntFreeP( &p->vMapFf2Ppi );
+ Vec_IntFreeP( &p->vMapPpi2Ff );
+ // terminary simulation
+ if ( p->pPars->fNewXSim )
+ Txs_ManStop( p->pTxs );
// internal use
Vec_IntFreeP( &p->vPrio ); // priority flops
Vec_IntFree( p->vLits ); // array of literals
@@ -162,9 +382,7 @@ void Pdr_ManStop( Pdr_Man_t * p )
Vec_IntFree( p->vVisits ); // intermediate
Vec_IntFree( p->vCi2Rem ); // CIs to be removed
Vec_IntFree( p->vRes ); // final result
- Vec_IntFree( p->vSuppLits ); // support literals
Vec_PtrFreeP( &p->vInfCubes );
- ABC_FREE( p->pCubeJust );
ABC_FREE( p->pTime4Outs );
if ( p->vCexes )
Vec_PtrFreeFree( p->vCexes );
@@ -197,7 +415,6 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p )
nFrames++;
// create the counter-example
pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig), Saig_ManPiNum(p->pAig), nFrames );
-// pCex->iPo = (p->pPars->iOutput==-1)? 0 : p->pPars->iOutput;
pCex->iPo = p->iOutCur;
pCex->iFrame = nFrames-1;
for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ )
@@ -206,6 +423,8 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p )
Lit = pObl->pState->Lits[i];
if ( lit_sign(Lit) )
continue;
+ if ( lit_var(Lit) >= pCex->nPis ) // allows PPI literals to be thrown away
+ continue;
assert( lit_var(Lit) < pCex->nPis );
Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) );
}
@@ -215,6 +434,112 @@ Abc_Cex_t * Pdr_ManDeriveCex( Pdr_Man_t * p )
return pCex;
}
+/**Function*************************************************************
+
+ Synopsis [Derives counter-example when abstraction is used.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Cex_t * Pdr_ManDeriveCexAbs( Pdr_Man_t * p )
+{
+ extern Gia_Man_t * Gia_ManDupAbs( Gia_Man_t * p, Vec_Int_t * vMapPpi2Ff, Vec_Int_t * vMapFf2Ppi );
+
+ Gia_Man_t * pAbs;
+ Abc_Cex_t * pCex, * pCexCare;
+ Pdr_Obl_t * pObl;
+ int i, f, Lit, Flop, nFrames = 0;
+ int nPis = Saig_ManPiNum(p->pAig);
+ int nFfRefined = 0;
+ if ( !p->pPars->fUseAbs || !p->vMapPpi2Ff )
+ return Pdr_ManDeriveCex(p);
+ // restore previous map
+ Vec_IntForEachEntry( p->vMapPpi2Ff, Flop, i )
+ {
+ assert( Vec_IntEntry( p->vMapFf2Ppi, Flop ) == i );
+ Vec_IntWriteEntry( p->vMapFf2Ppi, Flop, -1 );
+ }
+ Vec_IntClear( p->vMapPpi2Ff );
+ // count the number of frames
+ for ( pObl = p->pQueue; pObl; pObl = pObl->pNext )
+ {
+ for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ )
+ {
+ Lit = pObl->pState->Lits[i];
+ if ( lit_var(Lit) < nPis ) // PI literal
+ continue;
+ Flop = lit_var(Lit) - nPis;
+ if ( Vec_IntEntry(p->vMapFf2Ppi, Flop) >= 0 ) // already used PPI literal
+ continue;
+ Vec_IntWriteEntry( p->vMapFf2Ppi, Flop, Vec_IntSize(p->vMapPpi2Ff) );
+ Vec_IntPush( p->vMapPpi2Ff, Flop );
+ }
+ nFrames++;
+ }
+ if ( Vec_IntSize(p->vMapPpi2Ff) == 0 ) // no PPIs -- this is a real CEX
+ return Pdr_ManDeriveCex(p);
+ if ( p->pPars->fUseSimpleRef )
+ {
+ // rely on ternary simulation to perform refinement
+ Vec_IntForEachEntry( p->vMapPpi2Ff, Flop, i )
+ {
+ assert( Vec_IntEntry(p->vAbsFlops, Flop) == 0 );
+ Vec_IntWriteEntry( p->vAbsFlops, Flop, 1 );
+ nFfRefined++;
+ }
+ }
+ else
+ {
+ // create the counter-example
+ pCex = Abc_CexAlloc( Aig_ManRegNum(p->pAig) - Vec_IntSize(p->vMapPpi2Ff), Saig_ManPiNum(p->pAig) + Vec_IntSize(p->vMapPpi2Ff), nFrames );
+ pCex->iPo = p->iOutCur;
+ pCex->iFrame = nFrames-1;
+ for ( pObl = p->pQueue, f = 0; pObl; pObl = pObl->pNext, f++ )
+ for ( i = pObl->pState->nLits; i < pObl->pState->nTotal; i++ )
+ {
+ Lit = pObl->pState->Lits[i];
+ if ( lit_sign(Lit) )
+ continue;
+ if ( lit_var(Lit) < nPis ) // PI literal
+ Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + lit_var(Lit) );
+ else
+ {
+ int iPPI = nPis + Vec_IntEntry(p->vMapFf2Ppi, lit_var(Lit) - nPis);
+ assert( iPPI < pCex->nPis );
+ Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + iPPI );
+ }
+ }
+ assert( f == nFrames );
+ // perform CEX minimization
+ pAbs = Gia_ManDupAbs( p->pGia, p->vMapPpi2Ff, p->vMapFf2Ppi );
+ pCexCare = Bmc_CexCareMinimizeAig( pAbs, nPis, pCex, 1, 0, 0 );
+ Gia_ManStop( pAbs );
+ assert( pCexCare->nPis == pCex->nPis );
+ Abc_CexFree( pCex );
+ // detect care PPIs
+ for ( f = 0; f < nFrames; f++ )
+ {
+ for ( i = nPis; i < pCexCare->nPis; i++ )
+ if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) )
+ {
+ if ( Vec_IntEntry(p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis)) == 0 ) // currently abstracted
+ Vec_IntWriteEntry( p->vAbsFlops, Vec_IntEntry(p->vMapPpi2Ff, i-nPis), 1 ), nFfRefined++;
+ }
+ }
+ Abc_CexFree( pCexCare );
+ if ( nFfRefined == 0 ) // no refinement -- this is a real CEX
+ return Pdr_ManDeriveCex(p);
+ }
+ //printf( "CEX-based refinement refined %d flops.\n", nFfRefined );
+ p->nCexesTotal++;
+ p->nCexes++;
+ return NULL;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/pdr/pdrSat.c b/src/proof/pdr/pdrSat.c
index 2e6130aa..ab582d9e 100644
--- a/src/proof/pdr/pdrSat.c
+++ b/src/proof/pdr/pdrSat.c
@@ -51,7 +51,8 @@ sat_solver * Pdr_ManCreateSolver( Pdr_Man_t * p, int k )
assert( Vec_VecSize(p->vClauses) == k );
assert( Vec_IntSize(p->vActVars) == k );
// create new solver
- pSat = sat_solver_new();
+// pSat = sat_solver_new();
+ pSat = zsat_solver_new_seed(p->pPars->nRandomSeed);
pSat = Pdr_ManNewSolver( pSat, p, k, (int)(k == 0) );
Vec_PtrPush( p->vSolvers, pSat );
Vec_VecExpand( p->vClauses, k );
@@ -86,7 +87,8 @@ sat_solver * Pdr_ManFetchSolver( Pdr_Man_t * p, int k )
p->nStarts++;
// sat_solver_delete( pSat );
// pSat = sat_solver_new();
- sat_solver_restart( pSat );
+// sat_solver_restart( pSat );
+ zsat_solver_restart_seed( pSat, p->pPars->nRandomSeed );
// create new SAT solver
pSat = Pdr_ManNewSolver( pSat, p, k, (int)(k == 0) );
// write new SAT solver
@@ -285,9 +287,9 @@ int Pdr_ManCheckCubeCs( Pdr_Man_t * p, int k, Pdr_Set_t * pCube )
SeeAlso []
***********************************************************************/
-int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf )
+int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPred, int nConfLimit, int fTryConf, int fUseLit )
{
- int fUseLit = 1;
+ //int fUseLit = 0;
int fLitUsed = 0;
sat_solver * pSat;
Vec_Int_t * vLits;
@@ -340,24 +342,6 @@ int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPr
else
return -1;
}
-/*
- if ( RetValue == l_True )
- {
- int RetValue2 = Pdr_ManCubeJust( p, k, pCube );
- if ( RetValue2 )
- p->nCasesSS++;
- else
- p->nCasesSU++;
- }
- else
- {
- int RetValue2 = Pdr_ManCubeJust( p, k, pCube );
- if ( RetValue2 )
- p->nCasesUS++;
- else
- p->nCasesUU++;
- }
-*/
}
clk = Abc_Clock() - clk;
p->tSat += clk;
@@ -375,7 +359,16 @@ int Pdr_ManCheckCube( Pdr_Man_t * p, int k, Pdr_Set_t * pCube, Pdr_Set_t ** ppPr
p->tSatSat += clk;
p->nCallsS++;
if ( ppPred )
- *ppPred = Pdr_ManTernarySim( p, k, pCube );
+ {
+ abctime clk = Abc_Clock();
+ if ( p->pPars->fNewXSim )
+ *ppPred = Txs_ManTernarySim( p->pTxs, k, pCube );
+ else
+ *ppPred = Pdr_ManTernarySim( p, k, pCube );
+ p->tTsim += Abc_Clock() - clk;
+ p->nXsimLits += (*ppPred)->nLits;
+ p->nXsimRuns++;
+ }
RetValue = 0;
}
diff --git a/src/proof/pdr/pdrTsim.c b/src/proof/pdr/pdrTsim.c
index 32d1c857..acbf70f5 100644
--- a/src/proof/pdr/pdrTsim.c
+++ b/src/proof/pdr/pdrTsim.c
@@ -364,7 +364,7 @@ Pdr_Set_t * Pdr_ManTernarySim( Pdr_Man_t * p, int k, Pdr_Set_t * pCube )
Vec_Int_t * vRes = p->vRes; // final result (flop literals)
Aig_Obj_t * pObj;
int i, Entry, RetValue;
- abctime clk = Abc_Clock();
+ //abctime clk = Abc_Clock();
// collect CO objects
Vec_IntClear( vCoObjs );
@@ -404,67 +404,65 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, NULL );
RetValue = Pdr_ManSimDataInit( p->pAig, vCiObjs, vCiVals, vNodes, vCoObjs, vCoVals, NULL );
assert( RetValue );
-#if 1
- // try removing high-priority flops
- Vec_IntClear( vCi2Rem );
- Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
+ // iteratively remove flops
+ if ( p->pPars->fFlopPrio )
{
- if ( !Saig_ObjIsLo( p->pAig, pObj ) )
- continue;
- Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
- if ( vPrio != NULL && Vec_IntEntry( vPrio, Entry ) != 0 )
- continue;
- Vec_IntClear( vUndo );
- if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
- Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
- else
- Pdr_ManExtendUndo( p->pAig, vUndo );
- }
- // try removing low-priority flops
- Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
- {
- if ( !Saig_ObjIsLo( p->pAig, pObj ) )
- continue;
- Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
- if ( vPrio == NULL || Vec_IntEntry( vPrio, Entry ) == 0 )
- continue;
- Vec_IntClear( vUndo );
- if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
- Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
- else
- Pdr_ManExtendUndo( p->pAig, vUndo );
- }
-#else
- // try removing low-priority flops
- Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
- {
- if ( !Saig_ObjIsLo( p->pAig, pObj ) )
- continue;
- Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
- if ( vPrio == NULL || Vec_IntEntry( vPrio, Entry ) == 0 )
- continue;
- Vec_IntClear( vUndo );
- if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
- Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
- else
- Pdr_ManExtendUndo( p->pAig, vUndo );
+ // collect flops and sort them by priority
+ Vec_IntClear( vRes );
+ Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
+ {
+ if ( !Saig_ObjIsLo( p->pAig, pObj ) )
+ continue;
+ Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
+ Vec_IntPush( vRes, Entry );
+ }
+ Vec_IntSelectSortCost( Vec_IntArray(vRes), Vec_IntSize(vRes), vPrio );
+
+ // try removing flops starting from low-priority to high-priority
+ Vec_IntClear( vCi2Rem );
+ Vec_IntForEachEntry( vRes, Entry, i )
+ {
+ pObj = Aig_ManCi( p->pAig, Saig_ManPiNum(p->pAig) + Entry );
+ assert( Saig_ObjIsLo( p->pAig, pObj ) );
+ Vec_IntClear( vUndo );
+ if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
+ Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
+ else
+ Pdr_ManExtendUndo( p->pAig, vUndo );
+ }
}
- // try removing high-priority flops
- Vec_IntClear( vCi2Rem );
- Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
+ else
{
- if ( !Saig_ObjIsLo( p->pAig, pObj ) )
- continue;
- Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
- if ( vPrio != NULL && Vec_IntEntry( vPrio, Entry ) != 0 )
- continue;
- Vec_IntClear( vUndo );
- if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
- Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
- else
- Pdr_ManExtendUndo( p->pAig, vUndo );
+ // try removing low-priority flops first
+ Vec_IntClear( vCi2Rem );
+ Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
+ {
+ if ( !Saig_ObjIsLo( p->pAig, pObj ) )
+ continue;
+ Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
+ if ( Vec_IntEntry(vPrio, Entry) )
+ continue;
+ Vec_IntClear( vUndo );
+ if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
+ Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
+ else
+ Pdr_ManExtendUndo( p->pAig, vUndo );
+ }
+ // try removing high-priority flops next
+ Aig_ManForEachObjVec( vCiObjs, p->pAig, pObj, i )
+ {
+ if ( !Saig_ObjIsLo( p->pAig, pObj ) )
+ continue;
+ Entry = Aig_ObjCioId(pObj) - Saig_ManPiNum(p->pAig);
+ if ( !Vec_IntEntry(vPrio, Entry) )
+ continue;
+ Vec_IntClear( vUndo );
+ if ( Pdr_ManExtendOne( p->pAig, pObj, vUndo, vVisits ) )
+ Vec_IntPush( vCi2Rem, Aig_ObjId(pObj) );
+ else
+ Pdr_ManExtendUndo( p->pAig, vUndo );
+ }
}
-#endif
if ( p->pPars->fVeryVerbose )
Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem );
@@ -474,9 +472,25 @@ Pdr_ManPrintCex( p->pAig, vCiObjs, vCiVals, vCi2Rem );
// derive the set of resulting registers
Pdr_ManDeriveResult( p->pAig, vCiObjs, vCiVals, vCi2Rem, vRes, vPiLits );
assert( Vec_IntSize(vRes) > 0 );
- p->tTsim += Abc_Clock() - clk;
+ //p->tTsim += Abc_Clock() - clk;
+
+ // move abstracted literals from flops to inputs
+ if ( p->pPars->fUseAbs && p->vAbsFlops )
+ {
+ int i, iLit, k = 0;
+ Vec_IntForEachEntry( vRes, iLit, i )
+ {
+ if ( Vec_IntEntry(p->vAbsFlops, Abc_Lit2Var(iLit)) ) // used flop
+ Vec_IntWriteEntry( vRes, k++, iLit );
+ else
+ Vec_IntPush( vPiLits, 2*Saig_ManPiNum(p->pAig) + iLit );
+ }
+ Vec_IntShrink( vRes, k );
+ }
pRes = Pdr_SetCreate( vRes, vPiLits );
- assert( k == 0 || !Pdr_SetIsInit(pRes, -1) );
+ //ZH: Disabled assertion because this invariant doesn't hold with down
+ //because of the join operation which can bring in initial states
+ //assert( k == 0 || !Pdr_SetIsInit(pRes, -1) );
return pRes;
}
diff --git a/src/proof/pdr/pdrTsim2.c b/src/proof/pdr/pdrTsim2.c
new file mode 100644
index 00000000..8a86eecc
--- /dev/null
+++ b/src/proof/pdr/pdrTsim2.c
@@ -0,0 +1,550 @@
+/**CFile****************************************************************
+
+ FileName [pdrTsim.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Property driven reachability.]
+
+ Synopsis [Improved ternary simulation.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - November 20, 2010.]
+
+ Revision [$Id: pdrTsim.c,v 1.00 2010/11/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "pdrInt.h"
+#include "aig/gia/giaAig.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+struct Txs_Man_t_
+{
+ Gia_Man_t * pGia; // user's AIG
+ Vec_Int_t * vPrio; // priority of each flop
+ Vec_Int_t * vCiObjs; // cone leaves (CI obj IDs)
+ Vec_Int_t * vCoObjs; // cone roots (CO obj IDs)
+ Vec_Int_t * vCiVals; // cone leaf values (0/1 CI values)
+ Vec_Int_t * vCoVals; // cone root values (0/1 CO values)
+ Vec_Int_t * vNodes; // cone nodes (node obj IDs)
+ Vec_Int_t * vTemp; // cone nodes (node obj IDs)
+ Vec_Int_t * vPiLits; // resulting array of PI literals
+ Vec_Int_t * vFfLits; // resulting array of flop literals
+ Pdr_Man_t * pMan; // calling manager
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Start and stop the ternary simulation engine.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Txs_Man_t * Txs_ManStart( Pdr_Man_t * pMan, Aig_Man_t * pAig, Vec_Int_t * vPrio )
+{
+ Txs_Man_t * p;
+// Aig_Obj_t * pObj;
+// int i;
+ assert( Vec_IntSize(vPrio) == Aig_ManRegNum(pAig) );
+ p = ABC_CALLOC( Txs_Man_t, 1 );
+ p->pGia = Gia_ManFromAigSimple(pAig); // user's AIG
+// Aig_ManForEachObj( pAig, pObj, i )
+// assert( i == 0 || pObj->iData == Abc_Var2Lit(i, 0) );
+ p->vPrio = vPrio; // priority of each flop
+ p->vCiObjs = Vec_IntAlloc( 100 ); // cone leaves (CI obj IDs)
+ p->vCoObjs = Vec_IntAlloc( 100 ); // cone roots (CO obj IDs)
+ p->vCiVals = Vec_IntAlloc( 100 ); // cone leaf values (0/1 CI values)
+ p->vCoVals = Vec_IntAlloc( 100 ); // cone root values (0/1 CO values)
+ p->vNodes = Vec_IntAlloc( 100 ); // cone nodes (node obj IDs)
+ p->vTemp = Vec_IntAlloc( 100 ); // cone nodes (node obj IDs)
+ p->vPiLits = Vec_IntAlloc( 100 ); // resulting array of PI literals
+ p->vFfLits = Vec_IntAlloc( 100 ); // resulting array of flop literals
+ p->pMan = pMan; // calling manager
+ return p;
+}
+void Txs_ManStop( Txs_Man_t * p )
+{
+ Gia_ManStop( p->pGia );
+ Vec_IntFree( p->vCiObjs );
+ Vec_IntFree( p->vCoObjs );
+ Vec_IntFree( p->vCiVals );
+ Vec_IntFree( p->vCoVals );
+ Vec_IntFree( p->vNodes );
+ Vec_IntFree( p->vTemp );
+ Vec_IntFree( p->vPiLits );
+ Vec_IntFree( p->vFfLits );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Marks the TFI cone and collects CIs and nodes.]
+
+ Description [For this procedure to work Value should not be ~0
+ at the beginning.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Txs_ManCollectCone_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes )
+{
+ if ( !~pObj->Value )
+ return;
+ pObj->Value = ~0;
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ Vec_IntPush( vCiObjs, Gia_ObjId(p, pObj) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Txs_ManCollectCone_rec( p, Gia_ObjFanin0(pObj), vCiObjs, vNodes );
+ Txs_ManCollectCone_rec( p, Gia_ObjFanin1(pObj), vCiObjs, vNodes );
+ Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
+}
+void Txs_ManCollectCone( Gia_Man_t * p, Vec_Int_t * vCoObjs, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes )
+{
+ Gia_Obj_t * pObj; int i;
+// printf( "Collecting cones for clause with %d literals.\n", Vec_IntSize(vCoObjs) );
+ Vec_IntClear( vCiObjs );
+ Vec_IntClear( vNodes );
+ Gia_ManConst0(p)->Value = ~0;
+ Gia_ManForEachObjVec( vCoObjs, p, pObj, i )
+ Txs_ManCollectCone_rec( p, Gia_ObjFanin0(pObj), vCiObjs, vNodes );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate values and assign priority.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Txs_ManForwardPass( Gia_Man_t * p,
+ Vec_Int_t * vPrio, Vec_Int_t * vCiObjs, Vec_Int_t * vCiVals,
+ Vec_Int_t * vNodes, Vec_Int_t * vCoObjs, Vec_Int_t * vCoVals )
+{
+ Gia_Obj_t * pObj, * pFan0, * pFan1;
+ int i, value0, value1;
+ pObj = Gia_ManConst0(p);
+ pObj->fMark0 = 0;
+ pObj->fMark1 = 0;
+ Gia_ManForEachObjVec( vCiObjs, p, pObj, i )
+ {
+ pObj->fMark0 = Vec_IntEntry(vCiVals, i);
+ pObj->fMark1 = 0;
+ pObj->Value = Gia_ObjIsPi(p, pObj) ? 0x7FFFFFFF : Vec_IntEntry(vPrio, Gia_ObjCioId(pObj)-Gia_ManPiNum(p));
+ assert( ~pObj->Value );
+ }
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ {
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj);
+ value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj);
+ pObj->fMark0 = value0 && value1;
+ pObj->fMark1 = 0;
+ if ( pObj->fMark0 )
+ pObj->Value = Abc_MinInt( pFan0->Value, pFan1->Value );
+ else if ( value0 )
+ pObj->Value = pFan1->Value;
+ else if ( value1 )
+ pObj->Value = pFan0->Value;
+ else // if ( value0 == 0 && value1 == 0 )
+ pObj->Value = Abc_MaxInt( pFan0->Value, pFan1->Value );
+ assert( ~pObj->Value );
+ }
+ Gia_ManForEachObjVec( vCoObjs, p, pObj, i )
+ {
+ pFan0 = Gia_ObjFanin0(pObj);
+ pObj->fMark0 = (pFan0->fMark0 ^ Gia_ObjFaninC0(pObj));
+ pFan0->fMark1 = 1;
+ assert( (int)pObj->fMark0 == Vec_IntEntry(vCoVals, i) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate requirements and collect results.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Txs_ObjIsJust( Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ Gia_Obj_t * pFan0 = Gia_ObjFanin0(pObj);
+ Gia_Obj_t * pFan1 = Gia_ObjFanin1(pObj);
+ int value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj);
+ int value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj);
+ assert( Gia_ObjIsAnd(pObj) );
+ if ( pObj->fMark0 )
+ return pFan0->fMark1 && pFan1->fMark1;
+ assert( !pObj->fMark0 );
+ assert( !value0 || !value1 );
+ if ( value0 )
+ return pFan1->fMark1 || Gia_ObjIsPi(p, pFan1);
+ if ( value1 )
+ return pFan0->fMark1 || Gia_ObjIsPi(p, pFan0);
+ assert( !value0 && !value1 );
+ return pFan0->fMark1 || pFan1->fMark1 || Gia_ObjIsPi(p, pFan0) || Gia_ObjIsPi(p, pFan1);
+}
+void Txs_ManBackwardPass( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes, Vec_Int_t * vPiLits, Vec_Int_t * vFfLits )
+{
+ Gia_Obj_t * pObj, * pFan0, * pFan1; int i, value0, value1;
+ Gia_ManForEachObjVecReverse( vNodes, p, pObj, i )
+ {
+ if ( !pObj->fMark1 )
+ continue;
+ pObj->fMark1 = 0;
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( pObj->fMark0 )
+ {
+ pFan0->fMark1 = 1;
+ pFan1->fMark1 = 1;
+ continue;
+ }
+ value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj);
+ value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj);
+ assert( !value0 || !value1 );
+ if ( value0 )
+ pFan1->fMark1 = 1;
+ else if ( value1 )
+ pFan0->fMark1 = 1;
+ else // if ( !value0 && !value1 )
+ {
+ if ( pFan0->fMark1 || pFan1->fMark1 )
+ continue;
+ if ( Gia_ObjIsPi(p, pFan0) )
+ pFan0->fMark1 = 1;
+ else if ( Gia_ObjIsPi(p, pFan1) )
+ pFan1->fMark1 = 1;
+ else if ( Gia_ObjIsAnd(pFan0) && Txs_ObjIsJust(p, pFan0) )
+ pFan0->fMark1 = 1;
+ else if ( Gia_ObjIsAnd(pFan1) && Txs_ObjIsJust(p, pFan1) )
+ pFan1->fMark1 = 1;
+ else
+ {
+ if ( pFan0->Value >= pFan1->Value )
+ pFan0->fMark1 = 1;
+ else
+ pFan1->fMark1 = 1;
+ }
+ }
+ }
+ Vec_IntClear( vPiLits );
+ Vec_IntClear( vFfLits );
+ Gia_ManForEachObjVec( vCiObjs, p, pObj, i )
+ {
+ if ( !pObj->fMark1 )
+ continue;
+ if ( Gia_ObjIsPi(p, pObj) )
+ Vec_IntPush( vPiLits, Abc_Var2Lit(Gia_ObjCioId(pObj), !pObj->fMark0) );
+ else
+ Vec_IntPush( vFfLits, Abc_Var2Lit(Gia_ObjCioId(pObj)-Gia_ManPiNum(p), !pObj->fMark0) );
+ }
+ assert( Vec_IntSize(vFfLits) > 0 );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collects justification path.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Txs_ManSelectJustPath( Gia_Man_t * p, Vec_Int_t * vNodes, Vec_Int_t * vCoObjs, Vec_Int_t * vRes )
+{
+ Gia_Obj_t * pObj, * pFan0, * pFan1;
+ int i, value0, value1;
+ // mark CO drivers
+ Gia_ManForEachObjVec( vCoObjs, p, pObj, i )
+ Gia_ObjFanin0(pObj)->fMark1 = 1;
+ // collect just paths
+ Vec_IntClear( vRes );
+ Gia_ManForEachObjVecReverse( vNodes, p, pObj, i )
+ {
+ if ( !pObj->fMark1 )
+ continue;
+ pObj->fMark1 = 0;
+ Vec_IntPush( vRes, Gia_ObjId(p, pObj) );
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( pObj->fMark0 )
+ {
+ pFan0->fMark1 = 1;
+ pFan1->fMark1 = 1;
+ continue;
+ }
+ value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj);
+ value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj);
+ assert( !value0 || !value1 );
+ if ( value0 )
+ pFan1->fMark1 = 1;
+ else if ( value1 )
+ pFan0->fMark1 = 1;
+ else // if ( !value0 && !value1 )
+ {
+ pFan0->fMark1 = 1;
+ pFan1->fMark1 = 1;
+ }
+ }
+ Vec_IntReverseOrder( vRes );
+}
+void Txs_ManCollectJustPis( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vPiLits )
+{
+ Gia_Obj_t * pObj; int i;
+ Vec_IntClear( vPiLits );
+ Gia_ManForEachObjVec( vCiObjs, p, pObj, i )
+ if ( pObj->fMark1 && Gia_ObjIsPi(p, pObj) )
+ Vec_IntPush( vPiLits, Abc_Var2Lit(Gia_ObjCioId(pObj), !pObj->fMark0) );
+}
+void Txs_ManInitPrio( Gia_Man_t * p, Vec_Int_t * vCiObjs )
+{
+ Gia_Obj_t * pObj; int i;
+ Gia_ManConst0(p)->Value = 0x7FFFFFFF;
+ Gia_ManForEachObjVec( vCiObjs, p, pObj, i )
+ pObj->Value = Gia_ObjIsPi(p, pObj) ? 0x7FFFFFFF : Gia_ObjCioId(pObj) - Gia_ManPiNum(p);
+}
+void Txs_ManPropagatePrio( Gia_Man_t * p, Vec_Int_t * vNodes, Vec_Int_t * vPrio )
+{
+ Gia_Obj_t * pObj, * pFan0, * pFan1;
+ int i, value0, value1;
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ {
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ if ( pObj->fMark0 )
+ {
+// pObj->Value = Abc_MinInt( pFan0->Value, pFan1->Value );
+ if ( pFan0->Value == 0x7FFFFFFF )
+ pObj->Value = pFan1->Value;
+ else if ( pFan1->Value == 0x7FFFFFFF )
+ pObj->Value = pFan0->Value;
+ else if ( Vec_IntEntry(vPrio, pFan0->Value) < Vec_IntEntry(vPrio, pFan1->Value) )
+ pObj->Value = pFan0->Value;
+ else
+ pObj->Value = pFan1->Value;
+ continue;
+ }
+ value0 = pFan0->fMark0 ^ Gia_ObjFaninC0(pObj);
+ value1 = pFan1->fMark0 ^ Gia_ObjFaninC1(pObj);
+ assert( !value0 || !value1 );
+ if ( value0 )
+ pObj->Value = pFan1->Value;
+ else if ( value1 )
+ pObj->Value = pFan0->Value;
+ else // if ( value0 == 0 && value1 == 0 )
+ {
+// pObj->Value = Abc_MaxInt( pFan0->Value, pFan1->Value );
+ if ( pFan0->Value == 0x7FFFFFFF || pFan1->Value == 0x7FFFFFFF )
+ pObj->Value = 0x7FFFFFFF;
+ else if ( Vec_IntEntry(vPrio, pFan0->Value) >= Vec_IntEntry(vPrio, pFan1->Value) )
+ pObj->Value = pFan0->Value;
+ else
+ pObj->Value = pFan1->Value;
+ }
+ assert( ~pObj->Value );
+ }
+}
+int Txs_ManFindMinId( Gia_Man_t * p, Vec_Int_t * vCoObjs, Vec_Int_t * vPrio )
+{
+ Gia_Obj_t * pObj; int i, iMinId = -1;
+ Gia_ManForEachObjVec( vCoObjs, p, pObj, i )
+ if ( Gia_ObjFanin0(pObj)->Value != 0x7FFFFFFF )
+ {
+ if ( iMinId == -1 || Vec_IntEntry(vPrio, iMinId) > Vec_IntEntry(vPrio, Gia_ObjFanin0(pObj)->Value) )
+ iMinId = Gia_ObjFanin0(pObj)->Value;
+ }
+ return iMinId;
+}
+void Txs_ManFindCiReduction( Gia_Man_t * p,
+ Vec_Int_t * vPrio, Vec_Int_t * vCiObjs,
+ Vec_Int_t * vNodes, Vec_Int_t * vCoObjs,
+ Vec_Int_t * vPiLits, Vec_Int_t * vFfLits, Vec_Int_t * vTemp )
+{
+ Gia_Obj_t * pObj;
+ int iPrioCi;
+ // propagate PI influence
+ Txs_ManSelectJustPath( p, vNodes, vCoObjs, vTemp );
+ Txs_ManCollectJustPis( p, vCiObjs, vPiLits );
+// printf( "%d -> %d ", Vec_IntSize(vNodes), Vec_IntSize(vTemp) );
+ // iteratively detect and remove smallest IDs
+ Vec_IntClear( vFfLits );
+ Txs_ManInitPrio( p, vCiObjs );
+ while ( 1 )
+ {
+ Txs_ManPropagatePrio( p, vTemp, vPrio );
+ iPrioCi = Txs_ManFindMinId( p, vCoObjs, vPrio );
+ if ( iPrioCi == -1 )
+ break;
+ pObj = Gia_ManCi( p, Gia_ManPiNum(p)+iPrioCi );
+ Vec_IntPush( vFfLits, Abc_Var2Lit(iPrioCi, !pObj->fMark0) );
+ pObj->Value = 0x7FFFFFFF;
+ }
+}
+void Txs_ManPrintFlopLits( Vec_Int_t * vFfLits, Vec_Int_t * vPrio )
+{
+ int i, Entry;
+ printf( "%3d : ", Vec_IntSize(vFfLits) );
+ Vec_IntForEachEntry( vFfLits, Entry, i )
+ printf( "%s%d(%d) ", Abc_LitIsCompl(Entry)? "+":"-", Abc_Lit2Var(Entry), Vec_IntEntry(vPrio, Abc_Lit2Var(Entry)) );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Verify the result.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Txs_ManVerify( Gia_Man_t * p, Vec_Int_t * vCiObjs, Vec_Int_t * vNodes, Vec_Int_t * vPiLits, Vec_Int_t * vFfLits, Vec_Int_t * vCoObjs, Vec_Int_t * vCoVals )
+{
+ Gia_Obj_t * pObj;
+ int i, iLit;
+ Gia_ObjTerSimSet0( Gia_ManConst0(p) );
+ Gia_ManForEachObjVec( vCiObjs, p, pObj, i )
+ Gia_ObjTerSimSetX( pObj );
+ Vec_IntForEachEntry( vPiLits, iLit, i )
+ {
+ pObj = Gia_ManPi( p, Abc_Lit2Var(iLit) );
+ assert( Gia_ObjTerSimGetX(pObj) );
+ if ( Abc_LitIsCompl(iLit) )
+ Gia_ObjTerSimSet0( pObj );
+ else
+ Gia_ObjTerSimSet1( pObj );
+ }
+ Vec_IntForEachEntry( vFfLits, iLit, i )
+ {
+ pObj = Gia_ManCi( p, Gia_ManPiNum(p) + Abc_Lit2Var(iLit) );
+ assert( Gia_ObjTerSimGetX(pObj) );
+ if ( Abc_LitIsCompl(iLit) )
+ Gia_ObjTerSimSet0( pObj );
+ else
+ Gia_ObjTerSimSet1( pObj );
+ }
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ Gia_ObjTerSimAnd( pObj );
+ Gia_ManForEachObjVec( vCoObjs, p, pObj, i )
+ {
+ Gia_ObjTerSimCo( pObj );
+ if ( Vec_IntEntry(vCoVals, i) )
+ assert( Gia_ObjTerSimGet1(pObj) );
+ else
+ assert( Gia_ObjTerSimGet0(pObj) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Shrinks values using ternary simulation.]
+
+ Description [The cube contains the set of flop index literals which,
+ when converted into a clause and applied to the combinational outputs,
+ led to a satisfiable SAT run in frame k (values stored in the SAT solver).
+ If the cube is NULL, it is assumed that the first property output was
+ asserted and failed.
+ The resulting array is a set of flop index literals that asserts the COs.
+ Priority contains 0 for i-th entry if the i-th FF is desirable to remove.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Pdr_Set_t * Txs_ManTernarySim( Txs_Man_t * p, int k, Pdr_Set_t * pCube )
+{
+ int fTryNew = 1;
+ Pdr_Set_t * pRes;
+ Gia_Obj_t * pObj;
+ // collect CO objects
+ Vec_IntClear( p->vCoObjs );
+ if ( pCube == NULL ) // the target is the property output
+ {
+ pObj = Gia_ManCo(p->pGia, p->pMan->iOutCur);
+ Vec_IntPush( p->vCoObjs, Gia_ObjId(p->pGia, pObj) );
+ }
+ else // the target is the cube
+ {
+ int i;
+ for ( i = 0; i < pCube->nLits; i++ )
+ {
+ if ( pCube->Lits[i] == -1 )
+ continue;
+ pObj = Gia_ManCo(p->pGia, Gia_ManPoNum(p->pGia) + Abc_Lit2Var(pCube->Lits[i]));
+ Vec_IntPush( p->vCoObjs, Gia_ObjId(p->pGia, pObj) );
+ }
+ }
+if ( 0 )
+{
+Abc_Print( 1, "Trying to justify cube " );
+if ( pCube )
+ Pdr_SetPrint( stdout, pCube, Gia_ManRegNum(p->pGia), NULL );
+else
+ Abc_Print( 1, "<prop=fail>" );
+Abc_Print( 1, " in frame %d.\n", k );
+}
+
+ // collect CI objects
+ Txs_ManCollectCone( p->pGia, p->vCoObjs, p->vCiObjs, p->vNodes );
+ // collect values
+ Pdr_ManCollectValues( p->pMan, k, p->vCiObjs, p->vCiVals );
+ Pdr_ManCollectValues( p->pMan, k, p->vCoObjs, p->vCoVals );
+
+ // perform two passes
+ Txs_ManForwardPass( p->pGia, p->vPrio, p->vCiObjs, p->vCiVals, p->vNodes, p->vCoObjs, p->vCoVals );
+ if ( fTryNew )
+ Txs_ManFindCiReduction( p->pGia, p->vPrio, p->vCiObjs, p->vNodes, p->vCoObjs, p->vPiLits, p->vFfLits, p->vTemp );
+ else
+ Txs_ManBackwardPass( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits );
+ Txs_ManVerify( p->pGia, p->vCiObjs, p->vNodes, p->vPiLits, p->vFfLits, p->vCoObjs, p->vCoVals );
+
+ // derive the final set
+ pRes = Pdr_SetCreate( p->vFfLits, p->vPiLits );
+ //ZH: Disabled assertion because this invariant doesn't hold with down
+ //because of the join operation which can bring in initial states
+ //assert( k == 0 || !Pdr_SetIsInit(pRes, -1) );
+ return pRes;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/proof/pdr/pdrUtil.c b/src/proof/pdr/pdrUtil.c
index 53a8a54a..986697ac 100644
--- a/src/proof/pdr/pdrUtil.c
+++ b/src/proof/pdr/pdrUtil.c
@@ -260,6 +260,85 @@ void Pdr_SetPrint( FILE * pFile, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCoun
SeeAlso []
***********************************************************************/
+void ZPdr_SetPrint( Pdr_Set_t * p )
+{
+ int i;
+ for ( i = 0; i < p->nLits; i++)
+ printf ("%d ", p->Lits[i]);
+ printf ("\n");
+
+}
+
+/**Function*************************************************************
+
+ Synopsis [Return the intersection of p1 and p2.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Pdr_Set_t * ZPdr_SetIntersection( Pdr_Set_t * p1, Pdr_Set_t * p2, Hash_Int_t * keep )
+{
+ Pdr_Set_t * pIntersection;
+ Vec_Int_t * vCommonLits, * vPiLits;
+ int i, j, nLits;
+ nLits = p1->nLits;
+ if ( p2->nLits < nLits )
+ nLits = p2->nLits;
+ vCommonLits = Vec_IntAlloc( nLits );
+ vPiLits = Vec_IntAlloc( 1 );
+ for ( i = 0, j = 0; i < p1->nLits && j < p2->nLits; )
+ {
+ if ( p1->Lits[i] > p2->Lits[j] )
+ {
+ if ( Hash_IntExists( keep, p2->Lits[j] ) )
+ {
+ //about to drop a literal that should not be dropped
+ Vec_IntFree( vCommonLits );
+ Vec_IntFree( vPiLits );
+ return NULL;
+ }
+ j++;
+ }
+ else if ( p1->Lits[i] < p2->Lits[j] )
+ {
+ if ( Hash_IntExists( keep, p1->Lits[i] ) )
+ {
+ //about to drop a literal that should not be dropped
+ Vec_IntFree( vCommonLits );
+ Vec_IntFree( vPiLits );
+ return NULL;
+ }
+ i++;
+ }
+ else
+ {
+ Vec_IntPush( vCommonLits, p1->Lits[i] );
+ i++;
+ j++;
+ }
+ }
+ pIntersection = Pdr_SetCreate( vCommonLits, vPiLits );
+ Vec_IntFree( vCommonLits );
+ Vec_IntFree( vPiLits );
+ return pIntersection;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
void Pdr_SetPrintStr( Vec_Str_t * vStr, Pdr_Set_t * p, int nRegs, Vec_Int_t * vFlopCounts )
{
char * pBuff;
@@ -284,7 +363,7 @@ void Pdr_SetPrintStr( Vec_Str_t * vStr, Pdr_Set_t * p, int nRegs, Vec_Int_t * vF
}
Vec_StrPushBuffer( vStr, pBuff, k );
Vec_StrPush( vStr, ' ' );
- Vec_StrPush( vStr, '0' );
+ Vec_StrPush( vStr, '1' );
Vec_StrPush( vStr, '\n' );
ABC_FREE( pBuff );
}
@@ -674,8 +753,6 @@ int Pdr_NtkFindSatAssign_rec( Aig_Man_t * pAig, Aig_Obj_t * pNode, int Value, Pd
pNode->fMarkA = Value;
if ( Aig_ObjIsCi(pNode) )
{
-// if ( vSuppLits )
-// Vec_IntPush( vSuppLits, Abc_Var2Lit( Aig_ObjCioId(pNode), !Value ) );
if ( Saig_ObjIsLo(pAig, pNode) )
{
// pCube->Lits[pCube->nLits++] = Abc_Var2Lit( Aig_ObjCioId(pNode) - Saig_ManPiNum(pAig), !Value );
@@ -714,60 +791,6 @@ int Pdr_NtkFindSatAssign_rec( Aig_Man_t * pAig, Aig_Obj_t * pNode, int Value, Pd
return Pdr_NtkFindSatAssign_rec(pAig, Aig_ObjFanin0(pNode), Aig_ObjFaninC0(pNode), pCube, Heur);
}
-/**Function*************************************************************
-
- Synopsis [Returns 1 if SAT assignment is found; 0 otherwise.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Pdr_ManCubeJust( Pdr_Man_t * p, int k, Pdr_Set_t * pCube )
-{
- Aig_Obj_t * pNode;
- int i, v, fCompl;
-// return 0;
- for ( i = 0; i < 4; i++ )
- {
- // derive new assignment
- p->pCubeJust->nLits = 0;
- p->pCubeJust->Sign = 0;
- Aig_ManIncrementTravId( p->pAig );
- for ( v = 0; v < pCube->nLits; v++ )
- {
- if ( pCube->Lits[v] == -1 )
- continue;
- pNode = Saig_ManLi( p->pAig, lit_var(pCube->Lits[v]) );
- fCompl = lit_sign(pCube->Lits[v]) ^ Aig_ObjFaninC0(pNode);
- if ( !Pdr_NtkFindSatAssign_rec( p->pAig, Aig_ObjFanin0(pNode), !fCompl, p->pCubeJust, i ) )
- break;
- }
- if ( v < pCube->nLits )
- continue;
- // figure this out!!!
- if ( p->pCubeJust->nLits == 0 )
- continue;
- // successfully derived new assignment
- Vec_IntSelectSort( p->pCubeJust->Lits, p->pCubeJust->nLits );
- // check assignment against this cube
- if ( Pdr_SetContainsSimple( p->pCubeJust, pCube ) )
- continue;
-//printf( "\n" );
-//Pdr_SetPrint( stdout, pCube, Saig_ManRegNum(p->pAig), NULL ); printf( "\n" );
-//Pdr_SetPrint( stdout, p->pCubeJust, Saig_ManRegNum(p->pAig), NULL ); printf( "\n" );
- // check assignment against the clauses
- if ( Pdr_ManCheckContainment( p, k, p->pCubeJust ) )
- continue;
- // find good assignment
- return 1;
- }
- return 0;
-}
-
-
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////