summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2016-05-07 19:47:02 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2016-05-07 19:47:02 -0700
commit236d412255e5007adac97c05e759bfd5069bc1c1 (patch)
tree8b43abfb5798f47586e6f5dcd0acf8a07f61a722 /src
parent40d90ae69c4bb84e20e98aab127788a8b1755faa (diff)
downloadabc-236d412255e5007adac97c05e759bfd5069bc1c1.tar.gz
abc-236d412255e5007adac97c05e759bfd5069bc1c1.tar.bz2
abc-236d412255e5007adac97c05e759bfd5069bc1c1.zip
Experiments with CEC for arithmetic circuits.
Diffstat (limited to 'src')
-rw-r--r--src/aig/gia/gia.h6
-rw-r--r--src/aig/gia/giaBalLut.c4
-rw-r--r--src/aig/gia/giaDfs.c2
-rw-r--r--src/aig/gia/giaDup.c490
-rw-r--r--src/aig/gia/giaHash.c1
-rw-r--r--src/aig/gia/giaMuxes.c2
-rw-r--r--src/aig/gia/giaShow.c4
-rw-r--r--src/aig/gia/module.make2
-rw-r--r--src/base/abci/abc.c274
-rw-r--r--src/base/wlc/wlc.h1
-rw-r--r--src/base/wlc/wlcBlast.c1
-rw-r--r--src/base/wlc/wlcNtk.c5
-rw-r--r--src/base/wlc/wlcReadVer.c1
-rw-r--r--src/misc/vec/vecInt.h27
-rw-r--r--src/proof/acec/acec.c52
-rw-r--r--src/proof/acec/acec.h68
-rw-r--r--src/proof/acec/acecCore.c60
-rw-r--r--src/proof/acec/acecFadds.c (renamed from src/aig/gia/giaFadds.c)86
-rw-r--r--src/proof/acec/acecInt.h76
-rw-r--r--src/proof/acec/acecOrder.c178
-rw-r--r--src/proof/acec/acecPolyn.c (renamed from src/aig/gia/giaPolyn.c)249
-rw-r--r--src/proof/acec/acecUtil.c87
-rw-r--r--src/proof/acec/module.make5
23 files changed, 1405 insertions, 276 deletions
diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h
index 82e82cb2..390dbafb 100644
--- a/src/aig/gia/gia.h
+++ b/src/aig/gia/gia.h
@@ -1149,6 +1149,7 @@ extern Gia_Man_t * Gia_ManDupCofAllInt( Gia_Man_t * p, Vec_Int_t * vSigs
extern Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVerbose );
/*=== giaDfs.c ============================================================*/
extern void Gia_ManCollectCis( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vSupp );
+extern void Gia_ManCollectAnds_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vNodes );
extern void Gia_ManCollectAnds( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vNodes, Vec_Int_t * vLeaves );
extern Vec_Int_t * Gia_ManCollectNodesCis( Gia_Man_t * p, int * pNodes, int nNodes );
extern int Gia_ManSuppSize( Gia_Man_t * p, int * pNodes, int nNodes );
@@ -1209,10 +1210,15 @@ extern Gia_Man_t * Gia_ManTransformToDual( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManChoiceMiter( Vec_Ptr_t * vGias );
extern Gia_Man_t * Gia_ManDupWithConstraints( Gia_Man_t * p, Vec_Int_t * vPoTypes );
extern Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis );
+extern Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrimPis );
extern Gia_Man_t * Gia_ManDupOneHot( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupLevelized( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupFromVecs( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, int nRegs );
extern Gia_Man_t * Gia_ManDupSliced( Gia_Man_t * p, int nSuppMax );
+extern Gia_Man_t * Gia_ManDupDemiter( Gia_Man_t * p, int fVerbose );
+extern Gia_Man_t * Gia_ManDemiterToDual( Gia_Man_t * p );
+extern int Gia_ManDemiterDual( Gia_Man_t * p, Gia_Man_t ** pp0, Gia_Man_t ** pp1 );
+extern int Gia_ManDemiterTwoWords( Gia_Man_t * p, Gia_Man_t ** pp0, Gia_Man_t ** pp1 );
/*=== giaEdge.c ==========================================================*/
extern void Gia_ManEdgeFromArray( Gia_Man_t * p, Vec_Int_t * vArray );
extern Vec_Int_t * Gia_ManEdgeToArray( Gia_Man_t * p );
diff --git a/src/aig/gia/giaBalLut.c b/src/aig/gia/giaBalLut.c
index 73d2a6fb..4402e36f 100644
--- a/src/aig/gia/giaBalLut.c
+++ b/src/aig/gia/giaBalLut.c
@@ -568,7 +568,7 @@ static inline void Vec_IntSelectSortCostLit( Vec_Int_t * vSuper, Vec_Int_t * vCo
ABC_SWAP( int, pArray[i], pArray[best_i] );
}
}
-static inline void Vec_IntPushOrderCost( Vec_Int_t * vSuper, Vec_Int_t * vCosts, int iLit )
+static inline void Vec_IntPushOrderCost2( Vec_Int_t * vSuper, Vec_Int_t * vCosts, int iLit )
{
int i, nSize, * pArray;
Vec_IntPush( vSuper, iLit );
@@ -853,7 +853,7 @@ static inline int Gia_ManBalanceGate( Gia_Man_t * pNew, Gia_Obj_t * pObj, Vec_In
else
iLit = Gia_ManHashAnd( pNew, iBest, kBest );
Bal_ManSetGateLevel( p, pObj, iLit );
- Vec_IntPushOrderCost( vSuper, p->vCosts, iLit );
+ Vec_IntPushOrderCost2( vSuper, p->vCosts, iLit );
}
}
// consider trivial case
diff --git a/src/aig/gia/giaDfs.c b/src/aig/gia/giaDfs.c
index 60edef81..12cae940 100644
--- a/src/aig/gia/giaDfs.c
+++ b/src/aig/gia/giaDfs.c
@@ -136,7 +136,7 @@ void Gia_ManCollectAnds( Gia_Man_t * p, int * pNodes, int nNodes, Vec_Int_t * vN
Gia_Obj_t * pObj = Gia_ManObj( p, pNodes[i] );
if ( Gia_ObjIsCo(pObj) )
Gia_ManCollectAnds_rec( p, Gia_ObjFaninId0(pObj, pNodes[i]), vNodes );
- else
+ else if ( Gia_ObjIsAnd(pObj) )
Gia_ManCollectAnds_rec( p, pNodes[i], vNodes );
}
}
diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c
index e204fb55..a01c93fd 100644
--- a/src/aig/gia/giaDup.c
+++ b/src/aig/gia/giaDup.c
@@ -2950,6 +2950,65 @@ Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis )
return pNew;
}
+Gia_Man_t * Gia_ManDupAndCones( Gia_Man_t * p, int * pAnds, int nAnds, int fTrimPis )
+{
+ Gia_Man_t * pNew;
+ Vec_Ptr_t * vLeaves, * vNodes, * vRoots;
+ Gia_Obj_t * pObj;
+ int i;
+
+ // collect initial POs
+ vLeaves = Vec_PtrAlloc( 100 );
+ vNodes = Vec_PtrAlloc( 100 );
+ vRoots = Vec_PtrAlloc( 100 );
+ for ( i = 0; i < nAnds; i++ )
+// Vec_PtrPush( vRoots, Gia_ManPo(p, pPos[i]) );
+ Vec_PtrPush( vRoots, Gia_ManObj(p, pAnds[i]) );
+
+ // mark internal nodes
+ Gia_ManIncrementTravId( p );
+ Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
+ Vec_PtrForEachEntry( Gia_Obj_t *, vRoots, pObj, i )
+ Gia_ManDupCones_rec( p, pObj, vLeaves, vNodes, vRoots );
+ Vec_PtrSort( vLeaves, (int (*)(void))Gia_ObjCompareByCioId );
+
+ // start the new manager
+// Gia_ManFillValue( p );
+ pNew = Gia_ManStart( Vec_PtrSize(vLeaves) + Vec_PtrSize(vNodes) + Vec_PtrSize(vRoots) + 1);
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ // map the constant node
+ Gia_ManConst0(p)->Value = 0;
+ // create PIs
+ if ( fTrimPis )
+ {
+ Vec_PtrForEachEntry( Gia_Obj_t *, vLeaves, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ }
+ else
+ {
+ Gia_ManForEachPi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ }
+ // create LOs
+// Vec_PtrForEachEntryStart( Gia_Obj_t *, vRoots, pObj, i, nPos )
+// Gia_ObjRiToRo(p, pObj)->Value = Gia_ManAppendCi( pNew );
+ // create internal nodes
+ Vec_PtrForEachEntry( Gia_Obj_t *, vNodes, pObj, i )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ // create COs
+ Vec_PtrForEachEntry( Gia_Obj_t *, vRoots, pObj, i )
+// Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManAppendCo( pNew, pObj->Value );
+ // finalize
+// Gia_ManSetRegNum( pNew, Vec_PtrSize(vRoots)-nPos );
+ Gia_ManSetRegNum( pNew, 0 );
+ Vec_PtrFree( vLeaves );
+ Vec_PtrFree( vNodes );
+ Vec_PtrFree( vRoots );
+ return pNew;
+
+}
/**Function*************************************************************
@@ -3246,65 +3305,6 @@ int Gia_ManSortByValue( Gia_Obj_t ** pp1, Gia_Obj_t ** pp2 )
SeeAlso []
***********************************************************************/
-Gia_Man_t * Gia_ManDupDemiter( Gia_Man_t * p, int fVerbose )
-{
- Vec_Int_t * vSuper;
- Vec_Ptr_t * vSuperPtr;
- Gia_Man_t * pNew, * pTemp;
- Gia_Obj_t * pObj, * pObjPo;
- int i, iLit;
- assert( Gia_ManPoNum(p) == 1 );
- // decompose
- pObjPo = Gia_ManPo( p, 0 );
- vSuper = Vec_IntAlloc( 100 );
- Gia_ManDupWithConstrCollectAnd_rec( p, Gia_ObjFanin0(pObjPo), vSuper, 1 );
- assert( Vec_IntSize(vSuper) > 1 );
- // report the result
- printf( "The miter is %s-decomposable into %d parts.\n", Gia_ObjFaninC0(pObjPo) ? "OR":"AND", Vec_IntSize(vSuper) );
- // create levels
- Gia_ManLevelNum( p );
- Vec_IntForEachEntry( vSuper, iLit, i )
- Gia_ManObj(p, Abc_Lit2Var(iLit))->Value = Gia_ObjLevelId(p, Abc_Lit2Var(iLit));
- // create pointer array
- vSuperPtr = Vec_PtrAlloc( Vec_IntSize(vSuper) );
- Vec_IntForEachEntry( vSuper, iLit, i )
- Vec_PtrPush( vSuperPtr, Gia_Lit2Obj(p, iLit) );
- Vec_PtrSort( vSuperPtr, (int (*)(void))Gia_ManSortByValue );
- // create new manager
- 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_ManForEachAnd( p, pObj, i )
- pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
- // create the outputs
- Vec_PtrForEachEntry( Gia_Obj_t *, vSuperPtr, pObj, i )
- Gia_ManAppendCo( pNew, Gia_ObjLitCopy(p, Gia_Obj2Lit(p, pObj)) ^ Gia_ObjFaninC0(pObjPo) );
- Gia_ManForEachRi( p, pObj, i )
- Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
- Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
- // rehash
- pNew = Gia_ManCleanup( pTemp = pNew );
- Gia_ManStop( pTemp );
- Vec_IntFree( vSuper );
- Vec_PtrFree( vSuperPtr );
- return pNew;
-}
-
-/**Function*************************************************************
-
- Synopsis [Decomposes the miter outputs.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
Gia_Man_t * Gia_ManDupOuts( Gia_Man_t * p )
{
Gia_Man_t * pNew;
@@ -3583,6 +3583,378 @@ Gia_Man_t * Gia_ManIsoStrashReduce( Gia_Man_t * p, Vec_Ptr_t ** pvPosEquivs, int
return pNew;
}
+/**Function*************************************************************
+
+ Synopsis [Decomposes the miter outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupDemiter( Gia_Man_t * p, int fVerbose )
+{
+ Vec_Int_t * vSuper;
+ Vec_Ptr_t * vSuperPtr;
+ Gia_Man_t * pNew, * pTemp;
+ Gia_Obj_t * pObj, * pObjPo;
+ int i, iLit;
+ assert( Gia_ManPoNum(p) == 1 );
+ // decompose
+ pObjPo = Gia_ManPo( p, 0 );
+ vSuper = Vec_IntAlloc( 100 );
+ Gia_ManDupWithConstrCollectAnd_rec( p, Gia_ObjFanin0(pObjPo), vSuper, 1 );
+ assert( Vec_IntSize(vSuper) > 1 );
+ // report the result
+ printf( "The miter is %s-decomposable into %d parts.\n", Gia_ObjFaninC0(pObjPo) ? "OR":"AND", Vec_IntSize(vSuper) );
+ // create levels
+ Gia_ManLevelNum( p );
+ Vec_IntForEachEntry( vSuper, iLit, i )
+ Gia_ManObj(p, Abc_Lit2Var(iLit))->Value = Gia_ObjLevelId(p, Abc_Lit2Var(iLit));
+ // create pointer array
+ vSuperPtr = Vec_PtrAlloc( Vec_IntSize(vSuper) );
+ Vec_IntForEachEntry( vSuper, iLit, i )
+ Vec_PtrPush( vSuperPtr, Gia_Lit2Obj(p, iLit) );
+ Vec_PtrSort( vSuperPtr, (int (*)(void))Gia_ManSortByValue );
+ // create new manager
+ 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_ManForEachAnd( p, pObj, i )
+ pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ // create the outputs
+ Vec_PtrForEachEntry( Gia_Obj_t *, vSuperPtr, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjLitCopy(p, Gia_Obj2Lit(p, pObj)) ^ Gia_ObjFaninC0(pObjPo) );
+ Gia_ManForEachRi( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ // rehash
+ pNew = Gia_ManCleanup( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Vec_IntFree( vSuper );
+ Vec_PtrFree( vSuperPtr );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSetMark0Dfs_rec( Gia_Man_t * p, int iObj )
+{
+ Gia_Obj_t * pObj;
+ pObj = Gia_ManObj( p, iObj );
+ if ( pObj->fMark0 )
+ return;
+ pObj->fMark0 = 1;
+ if ( !Gia_ObjIsAnd(pObj) )
+ return;
+ Gia_ManSetMark0Dfs_rec( p, Gia_ObjFaninId0(pObj, iObj) );
+ Gia_ManSetMark0Dfs_rec( p, Gia_ObjFaninId1(pObj, iObj) );
+}
+void Gia_ManSetMark1Dfs_rec( Gia_Man_t * p, int iObj )
+{
+ Gia_Obj_t * pObj;
+ pObj = Gia_ManObj( p, iObj );
+ if ( pObj->fMark1 )
+ return;
+ pObj->fMark1 = 1;
+ if ( !Gia_ObjIsAnd(pObj) )
+ return;
+ Gia_ManSetMark1Dfs_rec( p, Gia_ObjFaninId0(pObj, iObj) );
+ Gia_ManSetMark1Dfs_rec( p, Gia_ObjFaninId1(pObj, iObj) );
+}
+
+int Gia_ManCountMark0Dfs_rec( Gia_Man_t * p, int iObj )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return 0;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( !Gia_ObjIsAnd(pObj) )
+ return pObj->fMark0;
+ return Gia_ManCountMark0Dfs_rec( p, Gia_ObjFaninId0(pObj, iObj) ) +
+ Gia_ManCountMark0Dfs_rec( p, Gia_ObjFaninId1(pObj, iObj) ) + pObj->fMark0;
+}
+int Gia_ManCountMark0Dfs( Gia_Man_t * p, int iObj )
+{
+ Gia_ManIncrementTravId( p );
+ return Gia_ManCountMark0Dfs_rec( p, iObj );
+}
+int Gia_ManCountMark1Dfs_rec( Gia_Man_t * p, int iObj )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return 0;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( !Gia_ObjIsAnd(pObj) )
+ return pObj->fMark1;
+ return Gia_ManCountMark1Dfs_rec( p, Gia_ObjFaninId0(pObj, iObj) ) +
+ Gia_ManCountMark1Dfs_rec( p, Gia_ObjFaninId1(pObj, iObj) ) + pObj->fMark1;
+}
+int Gia_ManCountMark1Dfs( Gia_Man_t * p, int iObj )
+{
+ Gia_ManIncrementTravId( p );
+ return Gia_ManCountMark1Dfs_rec( p, iObj );
+}
+
+int Gia_ManDecideWhereToAdd( Gia_Man_t * p, Vec_Int_t * vPart[2], Gia_Obj_t * pFan[2] )
+{
+ int Count0 = 1, Count1 = 0;
+ assert( Vec_IntSize(vPart[0]) == Vec_IntSize(vPart[1]) );
+ if ( Vec_IntSize(vPart[0]) > 0 )
+ {
+ Count0 = Gia_ManCountMark0Dfs(p, Gia_ObjId(p, pFan[0])) + Gia_ManCountMark1Dfs(p, Gia_ObjId(p, pFan[1]));
+ Count1 = Gia_ManCountMark0Dfs(p, Gia_ObjId(p, pFan[1])) + Gia_ManCountMark1Dfs(p, Gia_ObjId(p, pFan[0]));
+ }
+ return Count0 < Count1;
+}
+void Gia_ManCollectTopXors_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXors )
+{
+ Gia_Obj_t * pFan0, * pFan1;
+ int iObj = Gia_ObjId( p, pObj );
+ if ( Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) || !Gia_ObjIsAnd(pObj) )
+ {
+ Vec_IntPushUnique( vXors, Gia_ObjId(p, pObj) );
+ return;
+ }
+ if ( Gia_ObjFaninC0(pObj) )
+ Vec_IntPushUnique( vXors, Gia_ObjFaninId0(pObj, iObj) );
+ else
+ Gia_ManCollectTopXors_rec( p, Gia_ObjFanin0(pObj), vXors );
+ if ( Gia_ObjFaninC1(pObj) )
+ Vec_IntPushUnique( vXors, Gia_ObjFaninId1(pObj, iObj) );
+ else
+ Gia_ManCollectTopXors_rec( p, Gia_ObjFanin1(pObj), vXors );
+}
+Vec_Int_t * Gia_ManCollectTopXors( Gia_Man_t * p, Vec_Int_t * vPolar )
+{
+ int i, iObj, iObj2, fFlip, * pPerm, Count1 = 0;
+ Vec_Int_t * vXors, * vSizes, * vPart[2], * vOrder;
+ Gia_Obj_t * pFan[2], * pObj = Gia_ManCo(p, 0);
+ assert( Gia_ManCoNum(p) == 1 );
+ Vec_IntClear( vPolar );
+ if ( !Gia_ObjFaninC0(pObj) )
+ return NULL;
+ vXors = Vec_IntAlloc( 100 );
+ pObj = Gia_ObjFanin0(pObj);
+ if ( Gia_ObjIsAnd(pObj) )
+ Gia_ManCollectTopXors_rec( p, pObj, vXors );
+ else
+ Vec_IntPush( vXors, Gia_ObjId(p, pObj) );
+ // order by support size
+ vSizes = Vec_IntAlloc( 100 );
+ Vec_IntForEachEntry( vXors, iObj, i )
+ Vec_IntPush( vSizes, Gia_ManSuppSize(p, &iObj, 1) );
+ pPerm = Abc_MergeSortCost( Vec_IntArray(vSizes), Vec_IntSize(vSizes) );
+ Vec_IntClear( vSizes );
+ for ( i = 0; i < Vec_IntSize(vXors); i++ )
+ Vec_IntPush( vSizes, Vec_IntEntry(vXors, pPerm[i]) );
+ ABC_FREE( pPerm );
+ Vec_IntClear( vXors );
+ Vec_IntAppend( vXors, vSizes );
+ Vec_IntFree( vSizes );
+ Vec_IntReverseOrder( vXors ); // from MSB to LSB
+ // divide into groups
+ Gia_ManCleanMark01(p);
+ vPart[0] = Vec_IntAlloc( 100 );
+ vPart[1] = Vec_IntAlloc( 100 );
+ Gia_ManForEachObjVec( vXors, p, pObj, i )
+ {
+ int fCompl = 0;
+ if ( !Gia_ObjRecognizeExor(pObj, &pFan[0], &pFan[1]) )
+ pFan[0] = pObj, pFan[1] = Gia_ManConst0(p), Count1++;
+ else
+ {
+ fCompl ^= Gia_IsComplement(pFan[0]);
+ fCompl ^= Gia_IsComplement(pFan[1]);
+ pFan[0] = Gia_Regular(pFan[0]);
+ pFan[1] = Gia_Regular(pFan[1]);
+ }
+ Vec_IntPushTwo( vPolar, 0, fCompl );
+ fFlip = Gia_ManDecideWhereToAdd( p, vPart, pFan );
+ Vec_IntPush( vPart[0], Gia_ObjId(p, pFan[fFlip]) );
+ Vec_IntPush( vPart[1], Gia_ObjId(p, pFan[!fFlip]) );
+ Gia_ManSetMark0Dfs_rec( p, Gia_ObjId(p, pFan[fFlip]) );
+ Gia_ManSetMark1Dfs_rec( p, Gia_ObjId(p, pFan[!fFlip]) );
+ }
+ printf( "Detected %d single-output XOR miters and %d other miters.\n", Vec_IntSize(vXors) - Count1, Count1 );
+ Vec_IntFree( vXors );
+ Gia_ManCleanMark01(p);
+ // create new order
+ vOrder = Vec_IntAlloc( 100 );
+ Vec_IntForEachEntryTwo( vPart[0], vPart[1], iObj, iObj2, i )
+ Vec_IntPushTwo( vOrder, iObj, iObj2 );
+ Vec_IntFree( vPart[0] );
+ Vec_IntFree( vPart[1] );
+ Vec_IntReverseOrder( vOrder ); // from LSB to MSB
+ Vec_IntReverseOrder( vPolar );
+ //Vec_IntPrint( vOrder );
+ return vOrder;
+}
+Gia_Man_t * Gia_ManDemiterToDual( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew; Gia_Obj_t * pObj; int i;
+ Vec_Int_t * vNodes, * vPolar = Vec_IntAlloc( 100 );
+ Vec_Int_t * vOrder = Gia_ManCollectTopXors( p, vPolar );
+ if ( vOrder == NULL )
+ {
+ Vec_IntFree( vPolar );
+ printf( "Cannot demiter because the top-most gate is an AND-gate.\n" );
+ return NULL;
+ }
+ assert( Vec_IntSize(vOrder) == Vec_IntSize(vPolar) );
+ vNodes = Vec_IntAlloc( Gia_ManObjNum(p) );
+ Gia_ManIncrementTravId( p );
+ Gia_ManCollectAnds( p, Vec_IntArray(vOrder), Vec_IntSize(vOrder), vNodes, NULL );
+ pNew = Gia_ManStart( 1 + Gia_ManCiNum(p) + Vec_IntSize(vNodes) + Vec_IntSize(vOrder) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachObjVec( vOrder, p, pObj, i )
+ Gia_ManAppendCo( pNew, Abc_LitNotCond(pObj->Value, Vec_IntEntry(vPolar, i)) );
+ Vec_IntFree( vPolar );
+ Vec_IntFree( vNodes );
+ Vec_IntFree( vOrder );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collect nodes reachable from odd/even outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManCollectDfs_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vNodes )
+{
+ Gia_Obj_t * pObj;
+ if ( Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( !Gia_ObjIsAnd(pObj) )
+ return;
+ Gia_ManCollectDfs_rec( p, Gia_ObjFaninId0(pObj, iObj), vNodes );
+ Gia_ManCollectDfs_rec( p, Gia_ObjFaninId1(pObj, iObj), vNodes );
+ Vec_IntPush( vNodes, iObj );
+}
+Vec_Int_t * Gia_ManCollectReach( Gia_Man_t * p, int fOdd )
+{
+ int i, iDriver;
+ Vec_Int_t * vNodes = Vec_IntAlloc( Gia_ManObjNum(p) );
+ Gia_ManIncrementTravId( p );
+ Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
+ Gia_ManForEachCoDriverId( p, iDriver, i )
+ if ( (i & 1) == fOdd )
+ Gia_ManCollectDfs_rec( p, iDriver, vNodes );
+ return vNodes;
+}
+int Gia_ManDemiterDual( Gia_Man_t * p, Gia_Man_t ** pp0, Gia_Man_t ** pp1 )
+{
+ Gia_Obj_t * pObj;
+ int i, fOdd;
+ assert( Gia_ManRegNum(p) == 0 );
+ assert( Gia_ManCoNum(p) % 2 == 0 );
+ *pp0 = *pp1 = NULL;
+ for ( fOdd = 0; fOdd < 2; fOdd++ )
+ {
+ Vec_Int_t * vNodes = Gia_ManCollectReach( p, fOdd );
+ Gia_Man_t * pNew = Gia_ManStart( 1 + Gia_ManCiNum(p) + Vec_IntSize(vNodes) + Gia_ManCoNum(p)/2 );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachPi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ if ( (i & 1) == fOdd )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Vec_IntFree( vNodes );
+ if ( fOdd )
+ *pp1 = pNew;
+ else
+ *pp0 = pNew;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Collect nodes reachable from first/second half of outputs.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManCollectReach2( Gia_Man_t * p, int fSecond )
+{
+ int i, iDriver;
+ Vec_Int_t * vNodes = Vec_IntAlloc( Gia_ManObjNum(p) );
+ Gia_ManIncrementTravId( p );
+ Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
+ Gia_ManForEachCoDriverId( p, iDriver, i )
+ if ( (i < Gia_ManCoNum(p)/2) ^ fSecond )
+ Gia_ManCollectDfs_rec( p, iDriver, vNodes );
+ return vNodes;
+}
+int Gia_ManDemiterTwoWords( Gia_Man_t * p, Gia_Man_t ** pp0, Gia_Man_t ** pp1 )
+{
+ Gia_Obj_t * pObj;
+ int i, fSecond;
+ assert( Gia_ManRegNum(p) == 0 );
+ assert( Gia_ManCoNum(p) % 2 == 0 );
+ *pp0 = *pp1 = NULL;
+ for ( fSecond = 0; fSecond < 2; fSecond++ )
+ {
+ Vec_Int_t * vNodes = Gia_ManCollectReach2( p, fSecond );
+ Gia_Man_t * pNew = Gia_ManStart( 1 + Gia_ManCiNum(p) + Vec_IntSize(vNodes) + Gia_ManCoNum(p)/2 );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachPi( p, pObj, i )
+ pObj->Value = Gia_ManAppendCi( pNew );
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+ Gia_ManForEachCo( p, pObj, i )
+ if ( (i < Gia_ManCoNum(p)/2) ^ fSecond )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+ Vec_IntFree( vNodes );
+ if ( fSecond )
+ *pp1 = pNew;
+ else
+ *pp0 = pNew;
+ }
+ return 1;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/aig/gia/giaHash.c b/src/aig/gia/giaHash.c
index 58c65b99..725f03af 100644
--- a/src/aig/gia/giaHash.c
+++ b/src/aig/gia/giaHash.c
@@ -575,6 +575,7 @@ int Gia_ManHashMuxReal( Gia_Man_t * p, int iLitC, int iLit1, int iLit0 )
***********************************************************************/
int Gia_ManHashAnd( Gia_Man_t * p, int iLit0, int iLit1 )
{
+// return Gia_ManAppendAnd2( p, iLit0, iLit1 );
if ( iLit0 < 2 )
return iLit0 ? iLit1 : 0;
if ( iLit1 < 2 )
diff --git a/src/aig/gia/giaMuxes.c b/src/aig/gia/giaMuxes.c
index 3a55d6ca..c38cbf43 100644
--- a/src/aig/gia/giaMuxes.c
+++ b/src/aig/gia/giaMuxes.c
@@ -100,7 +100,7 @@ Gia_Man_t * Gia_ManDupMuxes( Gia_Man_t * p, int Limit )
Gia_Obj_t * pObj, * pFan0, * pFan1, * pFanC, * pSiblNew, * pObjNew;
int i;
assert( p->pMuxes == NULL );
- assert( Limit >= 2 );
+ assert( Limit >= 1 ); // allows to create AIG with XORs without MUXes
ABC_FREE( p->pRefs );
Gia_ManCreateRefs( p );
// start the new manager
diff --git a/src/aig/gia/giaShow.c b/src/aig/gia/giaShow.c
index fdb6c52e..6224d37f 100644
--- a/src/aig/gia/giaShow.c
+++ b/src/aig/gia/giaShow.c
@@ -50,9 +50,9 @@ void Gia_WriteDotAig( Gia_Man_t * pMan, char * pFileName, Vec_Int_t * vBold )
int LevelMax, Prev, Level, i;
int fConstIsUsed = 0;
- if ( Gia_ManAndNum(pMan) > 200 )
+ if ( Gia_ManAndNum(pMan) > 300 )
{
- fprintf( stdout, "Cannot visualize AIG with more than 200 nodes.\n" );
+ fprintf( stdout, "Cannot visualize AIG with more than 300 nodes.\n" );
return;
}
if ( (pFile = fopen( pFileName, "w" )) == NULL )
diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make
index 7da2858e..273597a4 100644
--- a/src/aig/gia/module.make
+++ b/src/aig/gia/module.make
@@ -23,7 +23,6 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaEra.c \
src/aig/gia/giaEra2.c \
src/aig/gia/giaEsop.c \
- src/aig/gia/giaFadds.c \
src/aig/gia/giaFalse.c \
src/aig/gia/giaFanout.c \
src/aig/gia/giaForce.c \
@@ -52,7 +51,6 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaPack.c \
src/aig/gia/giaPat.c \
src/aig/gia/giaPf.c \
- src/aig/gia/giaPolyn.c \
src/aig/gia/giaQbf.c \
src/aig/gia/giaResub.c \
src/aig/gia/giaRetime.c \
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index b88fa79d..6d6e16f5 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -43,6 +43,7 @@
#include "opt/ret/retInt.h"
#include "sat/cnf/cnf.h"
#include "proof/cec/cec.h"
+#include "proof/acec/acec.h"
#include "proof/pdr/pdr.h"
#include "misc/tim/tim.h"
#include "bdd/llb/llb.h"
@@ -464,6 +465,8 @@ static int Abc_CommandAbc9Bmci ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandAbc9PoXsim ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Demiter ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Fadds ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Polyn ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Acec ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Esop ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Exorcism ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandAbc9Mfs ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -1092,6 +1095,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "ABC9", "&poxsim", Abc_CommandAbc9PoXsim, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&demiter", Abc_CommandAbc9Demiter, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&fadds", Abc_CommandAbc9Fadds, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&polyn", Abc_CommandAbc9Polyn, 0 );
+ Cmd_CommandAdd( pAbc, "ABC9", "&acec", Abc_CommandAbc9Acec, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&esop", Abc_CommandAbc9Esop, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&exorcism", Abc_CommandAbc9Exorcism, 0 );
Cmd_CommandAdd( pAbc, "ABC9", "&mfs", Abc_CommandAbc9Mfs, 0 );
@@ -27760,6 +27765,7 @@ usage:
Abc_Print( -2, "\t-c : toggle collapsing hierarchical AIG [default = %s]\n", fCollapse? "yes": "no" );
Abc_Print( -2, "\t-m : toggle converting to larger gates [default = %s]\n", fAddMuxes? "yes": "no" );
Abc_Print( -2, "\t-L num : create MUX when sum of refs does not exceed this limit [default = %d]\n", Limit );
+ Abc_Print( -2, "\t (use L = 1 to create AIG with XORs but without MUXes)\n" );
Abc_Print( -2, "\t-r : toggle rehashing AIG while preserving mapping [default = %s]\n", fRehashMap? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -39054,14 +39060,22 @@ usage:
***********************************************************************/
int Abc_CommandAbc9Demiter( Abc_Frame_t * pAbc, int argc, char ** argv )
{
- extern Gia_Man_t * Gia_ManDupDemiter( Gia_Man_t * p, int fVerbose );
Gia_Man_t * pTemp;
- int c, fVerbose = 0;
+ int c, fDumpFiles = 0, fDumpFilesTwo = 0, fDual = 0, fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ftdvh" ) ) != EOF )
{
switch ( c )
{
+ case 'f':
+ fDumpFiles ^= 1;
+ break;
+ case 't':
+ fDumpFilesTwo ^= 1;
+ break;
+ case 'd':
+ fDual ^= 1;
+ break;
case 'v':
fVerbose ^= 1;
break;
@@ -39076,20 +39090,57 @@ int Abc_CommandAbc9Demiter( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Abc_CommandAbc9Demiter(): There is no AIG.\n" );
return 0;
}
+ if ( fDumpFiles || fDumpFilesTwo )
+ {
+ char pName0[1000] = "miter_part0.aig";
+ char pName1[1000] = "miter_part1.aig";
+ Gia_Man_t * pPart1, * pPart2;
+ if ( Gia_ManPoNum(pAbc->pGia) % 2 != 0 )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Demiter(): Does not look like a dual-output miter.\n" );
+ return 0;
+ }
+ if ( fDumpFilesTwo )
+ Gia_ManDemiterTwoWords( pAbc->pGia, &pPart1, &pPart2 );
+ else
+ Gia_ManDemiterDual( pAbc->pGia, &pPart1, &pPart2 );
+ if ( pAbc->pGia->pSpec )
+ {
+ char * pGen = Extra_FileNameGeneric(pAbc->pGia->pSpec);
+ sprintf( pName0, "%s_1.aig", pGen );
+ sprintf( pName1, "%s_2.aig", pGen );
+ ABC_FREE( pGen );
+ }
+ Gia_AigerWrite( pPart1, pName0, 0, 0 );
+ Gia_AigerWrite( pPart2, pName1, 0, 0 );
+ Gia_ManStop( pPart1 );
+ Gia_ManStop( pPart2 );
+ if ( fDumpFilesTwo )
+ printf( "Two parts of the two-word miter are dumped into files \"%s\" and \"%s\".\n", pName0, pName1 );
+ else
+ printf( "Two parts of the dual-output miter are dumped into files \"%s\" and \"%s\".\n", pName0, pName1 );
+ return 0;
+ }
if ( Gia_ManPoNum(pAbc->pGia) != 1 )
{
Abc_Print( -1, "Abc_CommandAbc9Demiter(): Miter should have one output.\n" );
return 0;
}
- pTemp = Gia_ManDupDemiter( pAbc->pGia, fVerbose );
+ if ( fDual )
+ pTemp = Gia_ManDemiterToDual( pAbc->pGia );
+ else
+ pTemp = Gia_ManDupDemiter( pAbc->pGia, fVerbose );
Abc_FrameUpdateGia( pAbc, pTemp );
if ( fVerbose )
Gia_ManPrintStatsMiter( pTemp, 0 );
return 0;
usage:
- Abc_Print( -2, "usage: &demiter [-vh]\n" );
- Abc_Print( -2, "\t decomposes a single-output miter\n" );
+ Abc_Print( -2, "usage: &demiter [-ftdvh]\n" );
+ Abc_Print( -2, "\t decomposes a miter (by default, tries to extract an OR gate)\n" );
+ Abc_Print( -2, "\t-f : write files with two sides of a dual-output miter [default = %s]\n", fDumpFiles? "yes": "no" );
+ Abc_Print( -2, "\t-t : write files with two sides of a two-word miter [default = %s]\n", fDumpFilesTwo? "yes": "no" );
+ Abc_Print( -2, "\t-d : take single-output and decompose into dual-output [default = %s]\n", fDual? "yes": "no" );
Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
@@ -39248,6 +39299,217 @@ usage:
SeeAlso []
***********************************************************************/
+int Abc_CommandAbc9Polyn( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ extern void Gia_PolynBuild( Gia_Man_t * pGia, Vec_Int_t * vOrder, int fVerbose );
+ int c, fVerbose = 0;
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'v':
+ fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Esop(): There is no AIG.\n" );
+ return 0;
+ }
+ Gia_PolynBuild( pAbc->pGia, NULL, fVerbose );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &polyn [-vh]\n" );
+ Abc_Print( -2, "\t derives algebraic polynomial from AIG\n" );
+ Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_CommandAbc9Acec( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+ FILE * pFile;
+ Cec_ParCec_t ParsCec, * pPars = &ParsCec;
+ Gia_Man_t * pSecond;
+ char * FileName, * pTemp;
+ char ** pArgvNew;
+ int c, nArgcNew, fMiter = 0, fDualOutput = 0, fTwoOutput = 0;
+ Cec_ManCecSetDefaultParams( pPars );
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdtvh" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'C':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nBTLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nBTLimit < 0 )
+ goto usage;
+ break;
+ case 'T':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->TimeLimit = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->TimeLimit < 0 )
+ goto usage;
+ break;
+ case 'n':
+ pPars->fNaive ^= 1;
+ break;
+ case 'm':
+ fMiter ^= 1;
+ break;
+ case 'd':
+ fDualOutput ^= 1;
+ break;
+ case 't':
+ fTwoOutput ^= 1;
+ break;
+ case 'v':
+ pPars->fVerbose ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+ if ( fMiter )
+ {
+ Gia_Man_t * pGia0, * pGia1, * pDual;
+ if ( pAbc->pGia == NULL )
+ {
+ Abc_Print( -1, "Abc_CommandAbc9Acec(): There is no AIG.\n" );
+ return 1;
+ }
+ if ( fDualOutput )
+ {
+ if ( Gia_ManPoNum(pAbc->pGia) & 1 )
+ {
+ Abc_Print( -1, "The dual-output miter should have an even number of outputs.\n" );
+ return 1;
+ }
+ if ( !pPars->fSilent )
+ Abc_Print( 1, "Assuming the current network is a double-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
+ Gia_ManDemiterDual( pAbc->pGia, &pGia0, &pGia1 );
+ pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars );
+ }
+ else if ( fTwoOutput )
+ {
+ if ( Gia_ManPoNum(pAbc->pGia) & 1 )
+ {
+ Abc_Print( -1, "The dual-output miter should have an even number of outputs.\n" );
+ return 1;
+ }
+ if ( !pPars->fSilent )
+ Abc_Print( 1, "Assuming the current network is a two-word miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
+ Gia_ManDemiterTwoWords( pAbc->pGia, &pGia0, &pGia1 );
+ pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars );
+ }
+ else
+ {
+ if ( !pPars->fSilent )
+ Abc_Print( 1, "Assuming the current network is a single-output miter. (Conflict limit = %d.)\n", pPars->nBTLimit );
+ pDual = Gia_ManDemiterToDual( pAbc->pGia );
+ Gia_ManDemiterDual( pDual, &pGia0, &pGia1 );
+ Gia_ManStop( pDual );
+ pAbc->Status = Gia_PolynCec( pGia0, pGia1, pPars );
+ }
+ Abc_FrameReplaceCex( pAbc, &pGia0->pCexComb );
+ Gia_ManStop( pGia0 );
+ Gia_ManStop( pGia1 );
+ return 0;
+ }
+
+ pArgvNew = argv + globalUtilOptind;
+ nArgcNew = argc - globalUtilOptind;
+ if ( nArgcNew != 1 )
+ {
+ if ( pAbc->pGia->pSpec == NULL )
+ {
+ Abc_Print( -1, "File name is not given on the command line.\n" );
+ return 1;
+ }
+ FileName = pAbc->pGia->pSpec;
+ }
+ else
+ FileName = pArgvNew[0];
+ // fix the wrong symbol
+ for ( pTemp = FileName; *pTemp; pTemp++ )
+ if ( *pTemp == '>' )
+ *pTemp = '\\';
+ if ( (pFile = fopen( FileName, "r" )) == NULL )
+ {
+ Abc_Print( -1, "Cannot open input file \"%s\". ", FileName );
+ if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) )
+ Abc_Print( 1, "Did you mean \"%s\"?", FileName );
+ Abc_Print( 1, "\n" );
+ return 1;
+ }
+ fclose( pFile );
+ pSecond = Gia_AigerRead( FileName, 0, 0 );
+ if ( pSecond == NULL )
+ {
+ Abc_Print( -1, "Reading AIGER has failed.\n" );
+ return 0;
+ }
+ pAbc->Status = Gia_PolynCec( pAbc->pGia, pSecond, pPars );
+ Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexComb );
+ Gia_ManStop( pSecond );
+ return 0;
+
+usage:
+ Abc_Print( -2, "usage: &acec [-CT num] [-nmdtvh]\n" );
+ Abc_Print( -2, "\t combinational equivalence checking for arithmetic circuits\n" );
+ Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
+ Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit );
+ Abc_Print( -2, "\t-n : toggle using naive SAT-based checking [default = %s]\n", pPars->fNaive? "yes":"no");
+ Abc_Print( -2, "\t-m : toggle miter vs. two circuits [default = %s]\n", fMiter? "miter":"two circuits");
+ Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", fDualOutput? "yes":"no");
+ Abc_Print( -2, "\t-t : toggle using two-word miter [default = %s]\n", fTwoOutput? "yes":"no");
+ Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no");
+ Abc_Print( -2, "\t-h : print the command usage\n");
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Abc_CommandAbc9Esop( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern Gia_Man_t * Eso_ManCompute( Gia_Man_t * pGia, int fVerbose, Vec_Wec_t ** pvRes );
diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h
index f3a4f7aa..453cb157 100644
--- a/src/base/wlc/wlc.h
+++ b/src/base/wlc/wlc.h
@@ -125,6 +125,7 @@ typedef struct Wlc_Ntk_t_ Wlc_Ntk_t;
struct Wlc_Ntk_t_
{
char * pName; // model name
+ char * pSpec; // input file name
Vec_Int_t vPis; // primary inputs
Vec_Int_t vPos; // primary outputs
Vec_Int_t vCis; // combinational inputs
diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c
index 3a3d614b..6ddd7a60 100644
--- a/src/base/wlc/wlcBlast.c
+++ b/src/base/wlc/wlcBlast.c
@@ -1327,6 +1327,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds )
}
assert( Vec_PtrSize(pNew->vNamesOut) == Gia_ManCoNum(pNew) );
*/
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec ? p->pSpec : p->pName );
return pNew;
}
diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c
index 2f3b07bf..442ddb83 100644
--- a/src/base/wlc/wlcNtk.c
+++ b/src/base/wlc/wlcNtk.c
@@ -223,6 +223,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p )
ABC_FREE( p->pInits );
ABC_FREE( p->pObjs );
ABC_FREE( p->pName );
+ ABC_FREE( p->pSpec );
ABC_FREE( p );
}
int Wlc_NtkMemUsage( Wlc_Ntk_t * p )
@@ -587,6 +588,8 @@ Wlc_Ntk_t * Wlc_NtkDupDfs( Wlc_Ntk_t * p )
if ( p->pInits )
pNew->pInits = Abc_UtilStrsav( p->pInits );
Vec_IntFree( vFanins );
+ if ( p->pSpec )
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
return pNew;
}
void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p )
@@ -658,6 +661,8 @@ Wlc_Ntk_t * Wlc_NtkDupSingleNodes( Wlc_Ntk_t * p )
}
Vec_IntFree( vFanins );
Wlc_NtkTransferNames( pNew, p );
+ if ( p->pSpec )
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
return pNew;
}
diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c
index 30525df4..0aedef30 100644
--- a/src/base/wlc/wlcReadVer.c
+++ b/src/base/wlc/wlcReadVer.c
@@ -1264,6 +1264,7 @@ Wlc_Ntk_t * Wlc_ReadVer( char * pFileName )
finish:
Wlc_PrsPrintErrorMessage( p );
Wlc_PrsStop( p );
+ pNtk->pSpec = Abc_UtilStrsav( pFileName );
return pNtk;
}
diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h
index e0e2ba7f..f09b8783 100644
--- a/src/misc/vec/vecInt.h
+++ b/src/misc/vec/vecInt.h
@@ -804,6 +804,24 @@ static inline void Vec_IntPushOrder( Vec_Int_t * p, int Entry )
break;
p->pArray[i+1] = Entry;
}
+static inline void Vec_IntPushOrderCost( Vec_Int_t * p, int Entry, Vec_Int_t * vCost )
+{
+ int i;
+ if ( p->nSize == p->nCap )
+ {
+ if ( p->nCap < 16 )
+ Vec_IntGrow( p, 16 );
+ else
+ Vec_IntGrow( p, 2 * p->nCap );
+ }
+ p->nSize++;
+ for ( i = p->nSize-2; i >= 0; i-- )
+ if ( Vec_IntEntry(vCost, p->pArray[i]) > Vec_IntEntry(vCost, Entry) )
+ p->pArray[i+1] = p->pArray[i];
+ else
+ break;
+ p->pArray[i+1] = Entry;
+}
/**Function*************************************************************
@@ -855,6 +873,15 @@ static inline int Vec_IntPushUniqueOrder( Vec_Int_t * p, int Entry )
Vec_IntPushOrder( p, Entry );
return 0;
}
+static inline int Vec_IntPushUniqueOrderCost( Vec_Int_t * p, int Entry, Vec_Int_t * vCost )
+{
+ int i;
+ for ( i = 0; i < p->nSize; i++ )
+ if ( p->pArray[i] == Entry )
+ return 1;
+ Vec_IntPushOrderCost( p, Entry, vCost );
+ return 0;
+}
/**Function*************************************************************
diff --git a/src/proof/acec/acec.c b/src/proof/acec/acec.c
new file mode 100644
index 00000000..4237ef18
--- /dev/null
+++ b/src/proof/acec/acec.c
@@ -0,0 +1,52 @@
+/**CFile****************************************************************
+
+ FileName [acec.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis []
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acec.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 []
+
+***********************************************************************/
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/acec.h b/src/proof/acec/acec.h
new file mode 100644
index 00000000..3f05e5e6
--- /dev/null
+++ b/src/proof/acec/acec.h
@@ -0,0 +1,68 @@
+/**CFile****************************************************************
+
+ FileName [acec.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef ABC__proof__acec__acec_h
+#define ABC__proof__acec__acec_h
+
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_HEADER_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// ITERATORS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== acecCore.c ========================================================*/
+extern int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars );
+/*=== acecMiter.c ========================================================*/
+extern int Gia_ManDemiterDual( Gia_Man_t * p, Gia_Man_t ** pp0, Gia_Man_t ** pp1 );
+extern int Gia_ManDemiterXor( Gia_Man_t * p, Gia_Man_t ** pp0, Gia_Man_t ** pp1 );
+
+
+ABC_NAMESPACE_HEADER_END
+
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/proof/acec/acecCore.c b/src/proof/acec/acecCore.c
new file mode 100644
index 00000000..bfece8dc
--- /dev/null
+++ b/src/proof/acec/acecCore.c
@@ -0,0 +1,60 @@
+/**CFile****************************************************************
+
+ FileName [acecCore.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: acecCore.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 []
+
+***********************************************************************/
+int Gia_PolynCec( Gia_Man_t * pGia0, Gia_Man_t * pGia1, Cec_ParCec_t * pPars )
+{
+ Vec_Int_t * vOrder0 = Gia_PolynReorder( pGia0, pPars->fVerbose );
+ Vec_Int_t * vOrder1 = Gia_PolynReorder( pGia1, pPars->fVerbose );
+ Gia_PolynBuild( pGia0, vOrder0, pPars->fVerbose );
+ Gia_PolynBuild( pGia1, vOrder1, pPars->fVerbose );
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaFadds.c b/src/proof/acec/acecFadds.c
index 4014814a..3d526dbf 100644
--- a/src/aig/gia/giaFadds.c
+++ b/src/proof/acec/acecFadds.c
@@ -1,12 +1,12 @@
/**CFile****************************************************************
- FileName [giaFadds.c]
+ FileName [acecFadds.c]
SystemName [ABC: Logic synthesis and verification system.]
- PackageName [Scalable AIG package.]
+ PackageName [CEC for arithmetic circuits.]
- Synopsis [Extraction of full-adders.]
+ Synopsis [Detecting half-adders and full-adders.]
Author [Alan Mishchenko]
@@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
- Revision [$Id: giaFadds.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+ Revision [$Id: acecFadds.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
-#include "gia.h"
+#include "acecInt.h"
#include "misc/vec/vecWec.h"
#include "misc/tim/tim.h"
@@ -38,6 +38,70 @@ ABC_NAMESPACE_IMPL_START
/**Function*************************************************************
+ Synopsis [Detecting HADDs in the AIG.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Gia_ManDetectHalfAdders( Gia_Man_t * p, int fVerbose )
+{
+ Vec_Int_t * vHadds = Vec_IntAlloc( 1000 );
+ Gia_Obj_t * pObj, * pFan0, * pFan1;
+ int i, iLit, iFan0, iFan1, fComplDiff, Count, Counts[5] = {0};
+ ABC_FREE( p->pRefs );
+ Gia_ManCreateRefs( p );
+ Gia_ManHashStart( p );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
+ continue;
+ Count = 0;
+ if ( Gia_ObjRefNumId(p, Gia_ObjFaninId0(pObj, i)) > 1 )
+ Vec_IntPushTwo( vHadds, i, Gia_ObjFaninId0(pObj, i) ), Count++;
+ if ( Gia_ObjRefNumId(p, Gia_ObjFaninId1(pObj, i)) > 1 )
+ Vec_IntPushTwo( vHadds, i, Gia_ObjFaninId1(pObj, i) ), Count++;
+ iFan0 = Gia_ObjId( p, pFan0 );
+ iFan1 = Gia_ObjId( p, pFan1 );
+ fComplDiff = (Gia_ObjFaninC0(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC1(Gia_ObjFanin0(pObj)));
+ assert( fComplDiff == (Gia_ObjFaninC0(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(Gia_ObjFanin1(pObj))) );
+ if ( fComplDiff )
+ {
+ if ( (iLit = Gia_ManHashLookupInt(p, Abc_Var2Lit(iFan0, 0), Abc_Var2Lit(iFan1, 0))) )
+ Vec_IntPushTwo( vHadds, i, Abc_Lit2Var(iLit) ), Count++;
+ if ( (iLit = Gia_ManHashLookupInt(p, Abc_Var2Lit(iFan0, 1), Abc_Var2Lit(iFan1, 1))) )
+ Vec_IntPushTwo( vHadds, i, Abc_Lit2Var(iLit) ), Count++;
+ }
+ else
+ {
+ if ( (iLit = Gia_ManHashLookupInt(p, Abc_Var2Lit(iFan0, 0), Abc_Var2Lit(iFan1, 1))) )
+ Vec_IntPushTwo( vHadds, i, Abc_Lit2Var(iLit) ), Count++;
+ if ( (iLit = Gia_ManHashLookupInt(p, Abc_Var2Lit(iFan0, 1), Abc_Var2Lit(iFan1, 0))) )
+ Vec_IntPushTwo( vHadds, i, Abc_Lit2Var(iLit) ), Count++;
+ }
+ Counts[Count]++;
+ }
+ Gia_ManHashStop( p );
+ ABC_FREE( p->pRefs );
+ if ( fVerbose )
+ {
+ int iXor, iAnd;
+ printf( "Found %d half-adders with XOR gates: ", Vec_IntSize(vHadds)/2 );
+ for ( i = 0; i <= 4; i++ )
+ printf( "%d=%d ", i, Counts[i] );
+ printf( "\n" );
+
+ Vec_IntForEachEntryDouble( vHadds, iXor, iAnd, i )
+ printf( "%3d : %5d %5d\n", i, iXor, iAnd );
+ }
+ return vHadds;
+}
+
+/**Function*************************************************************
+
Synopsis [Derive GIA with boxes containing adder-chains.]
Description []
@@ -176,6 +240,7 @@ int Dtc_ObjComputeTruth( Gia_Man_t * p, int iObj, int * pCut, int * pTruth )
}
void Dtc_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_Int_t * vCuts, Vec_Int_t * vCutsXor, Vec_Int_t * vCutsMaj )
{
+ int fVerbose = 0;
Vec_Int_t * vTemp;
int i, k, c, Type, * pCut0, * pCut1, pCut[4];
Vec_IntFill( vCuts, 2, 1 );
@@ -196,8 +261,16 @@ void Dtc_ManCutMerge( Gia_Man_t * p, int iObj, int * pList0, int * pList1, Vec_I
if ( Type == 0 )
continue;
vTemp = Type == 1 ? vCutsXor : vCutsMaj;
+ if ( fVerbose )
+ printf( "%d = %s(", iObj, Type == 1 ? "XOR" : "MAJ" );
for ( c = 1; c <= pCut[0]; c++ )
+ {
+ if ( fVerbose )
+ printf( " %d", pCut[c] );
Vec_IntPush( vTemp, pCut[c] );
+ }
+ if ( fVerbose )
+ printf( " )\n" );
Vec_IntPush( vTemp, iObj );
}
}
@@ -307,7 +380,8 @@ Vec_Int_t * Gia_ManDetectFullAdders( Gia_Man_t * p, int fVerbose )
qsort( Vec_IntArray(vFadds), Vec_IntSize(vFadds)/5, 20, (int (*)(const void *, const void *))Dtc_ManCompare2 );
if ( fVerbose )
printf( "XOR3 cuts = %d. MAJ cuts = %d. Full-adders = %d.\n", Vec_IntSize(vCutsXor)/4, Vec_IntSize(vCutsMaj)/4, Vec_IntSize(vFadds)/5 );
- //Dtc_ManPrintFadds( vFadds );
+ if ( fVerbose )
+ Dtc_ManPrintFadds( vFadds );
Vec_IntFree( vCutsXor );
Vec_IntFree( vCutsMaj );
return vFadds;
diff --git a/src/proof/acec/acecInt.h b/src/proof/acec/acecInt.h
new file mode 100644
index 00000000..28e8740b
--- /dev/null
+++ b/src/proof/acec/acecInt.h
@@ -0,0 +1,76 @@
+/**CFile****************************************************************
+
+ FileName [acecInt.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Internal declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef ABC__proof__acec__acec__int_h
+#define ABC__proof__acec__acec__int_h
+
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+#include "aig/gia/gia.h"
+#include "proof/cec/cec.h"
+#include "acec.h"
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_HEADER_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// ITERATORS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== acecFadds.c ========================================================*/
+extern Vec_Int_t * Gia_ManDetectFullAdders( Gia_Man_t * p, int fVerbose );
+extern Vec_Int_t * Gia_ManDetectHalfAdders( Gia_Man_t * p, int fVerbose );
+/*=== acecOrder.c ========================================================*/
+extern Vec_Int_t * Gia_PolynReorder( Gia_Man_t * pGia, int fVerbose );
+/*=== acecPolyn.c ========================================================*/
+extern void Gia_PolynBuild( Gia_Man_t * pGia, Vec_Int_t * vOrder, int fVerbose );
+/*=== acecUtil.c ========================================================*/
+extern void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose );
+
+ABC_NAMESPACE_HEADER_END
+
+
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/proof/acec/acecOrder.c b/src/proof/acec/acecOrder.c
new file mode 100644
index 00000000..0cf686c8
--- /dev/null
+++ b/src/proof/acec/acecOrder.c
@@ -0,0 +1,178 @@
+/**CFile****************************************************************
+
+ FileName [acecOrder.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Node ordering.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecOrder.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 []
+
+***********************************************************************/
+Vec_Int_t * Gia_PolynReorder( Gia_Man_t * pGia, int fVerbose )
+{
+ int fDumpLeftOver = 0;
+ Vec_Int_t * vOrder, * vOrder2;
+ Gia_Obj_t * pFan0, * pFan1;
+ int i, k, iDriver, Iter, iXor, iMaj, Entry, fFound;
+ Vec_Int_t * vFadds = Gia_ManDetectFullAdders( pGia, fVerbose );
+ Vec_Int_t * vHadds = Gia_ManDetectHalfAdders( pGia, fVerbose );
+ Vec_Int_t * vRecord = Vec_IntAlloc( 100 );
+
+ Vec_Int_t * vMap = Vec_IntStart( Gia_ManObjNum(pGia) );
+ Gia_ManForEachCoDriverId( pGia, iDriver, i )
+ Vec_IntWriteEntry( vMap, iDriver, 1 );
+
+ for ( Iter = 0; ; Iter++ )
+ {
+ int fFoundAll = 0;
+ printf( "Iteration %d\n", Iter );
+
+ // find the last one
+ iDriver = -1;
+ Vec_IntForEachEntryReverse( vMap, Entry, i )
+ if ( Entry )
+ {
+ iDriver = i;
+ break;
+ }
+
+ if ( iDriver > 0 && Gia_ObjRecognizeExor(Gia_ManObj(pGia, iDriver), &pFan0, &pFan1) && Vec_IntFind(vFadds, iDriver) == -1 && Vec_IntFind(vHadds, iDriver) == -1 )
+ {
+ Vec_IntWriteEntry( vMap, iDriver, 0 );
+ Vec_IntWriteEntry( vMap, Gia_ObjId(pGia, pFan0), 1 );
+ Vec_IntWriteEntry( vMap, Gia_ObjId(pGia, pFan1), 1 );
+ Vec_IntPush( vRecord, iDriver );
+ printf( "Recognizing %d => XOR(%d %d)\n", iDriver, Gia_ObjId(pGia, pFan0), Gia_ObjId(pGia, pFan1) );
+ }
+
+ // check if we can extract FADDs
+ do {
+ fFound = 0;
+ for ( i = 0; i < Vec_IntSize(vFadds)/5; i++ )
+ {
+ iXor = Vec_IntEntry(vFadds, 5*i+3);
+ iMaj = Vec_IntEntry(vFadds, 5*i+4);
+ if ( Vec_IntEntry(vMap, iXor) && Vec_IntEntry(vMap, iMaj) )
+ {
+ Vec_IntWriteEntry( vMap, iXor, 0 );
+ Vec_IntWriteEntry( vMap, iMaj, 0 );
+ Vec_IntWriteEntry( vMap, Vec_IntEntry(vFadds, 5*i+0), 1 );
+ Vec_IntWriteEntry( vMap, Vec_IntEntry(vFadds, 5*i+1), 1 );
+ Vec_IntWriteEntry( vMap, Vec_IntEntry(vFadds, 5*i+2), 1 );
+ Vec_IntPush( vRecord, iXor );
+ Vec_IntPush( vRecord, iMaj );
+ fFound = 1;
+ fFoundAll = 1;
+ printf( "Recognizing (%d %d) => FA(%d %d %d)\n", iXor, iMaj, Vec_IntEntry(vFadds, 5*i+0), Vec_IntEntry(vFadds, 5*i+1), Vec_IntEntry(vFadds, 5*i+2) );
+ }
+ }
+ } while ( fFound );
+ // check if we can extract HADDs
+ do {
+ fFound = 0;
+ Vec_IntForEachEntryDouble( vHadds, iXor, iMaj, i )
+ {
+ if ( Vec_IntEntry(vMap, iXor) && Vec_IntEntry(vMap, iMaj) )
+ {
+ Gia_Obj_t * pAnd = Gia_ManObj( pGia, iMaj );
+ Vec_IntWriteEntry( vMap, iXor, 0 );
+ Vec_IntWriteEntry( vMap, iMaj, 0 );
+ Vec_IntWriteEntry( vMap, Gia_ObjFaninId0(pAnd, iMaj), 1 );
+ Vec_IntWriteEntry( vMap, Gia_ObjFaninId1(pAnd, iMaj), 1 );
+ Vec_IntPush( vRecord, iXor );
+ Vec_IntPush( vRecord, iMaj );
+ fFound = 1;
+ fFoundAll = 1;
+ printf( "Recognizing (%d %d) => HA(%d %d)\n", iXor, iMaj, Gia_ObjFaninId0(pAnd, iMaj), Gia_ObjFaninId1(pAnd, iMaj) );
+ }
+ }
+ } while ( fFound );
+ if ( fFoundAll == 0 )
+ break;
+ }
+
+ //Vec_IntPrint( vRecord );
+ printf( "Remaining: " );
+ Vec_IntForEachEntry( vMap, Entry, i )
+ if ( Entry )
+ printf( "%d ", i );
+ printf( "\n" );
+
+ // collect remaining nodes
+ k = 0;
+ Vec_IntForEachEntry( vMap, Entry, i )
+ if ( Entry && Gia_ObjIsAnd(Gia_ManObj(pGia, i)) )
+ Vec_IntWriteEntry( vMap, k++, i );
+ Vec_IntShrink( vMap, k );
+
+ // dump remaining nodes as an AIG
+ if ( fDumpLeftOver )
+ {
+ Gia_Man_t * pNew = Gia_ManDupAndCones( pGia, Vec_IntArray(vMap), Vec_IntSize(vMap), 0 );
+ Gia_AigerWrite( pNew, "leftover.aig", 0, 0 );
+ Gia_ManStop( pNew );
+ }
+
+ // collect nodes
+ vOrder = Vec_IntAlloc( Gia_ManAndNum(pGia) );
+ Gia_ManIncrementTravId( pGia );
+ Gia_ManCollectAnds( pGia, Vec_IntArray(vMap), Vec_IntSize(vMap), vOrder, NULL );
+ Vec_IntForEachEntryReverse( vRecord, Entry, i )
+ Gia_ManCollectAnds_rec( pGia, Entry, vOrder );
+ assert( Vec_IntSize(vOrder) == Gia_ManAndNum(pGia) );
+
+ // remap order
+ vOrder2 = Vec_IntStart( Gia_ManObjNum(pGia) );
+ Vec_IntForEachEntry( vOrder, Entry, i )
+ Vec_IntWriteEntry( vOrder2, Entry, i+1 );
+ Vec_IntFree( vOrder );
+
+ Vec_IntFree( vMap );
+ Vec_IntFree( vRecord );
+ Vec_IntFree( vFadds );
+ Vec_IntFree( vHadds );
+ return vOrder2;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaPolyn.c b/src/proof/acec/acecPolyn.c
index 4e8d7378..df6ef2a2 100644
--- a/src/aig/gia/giaPolyn.c
+++ b/src/proof/acec/acecPolyn.c
@@ -1,12 +1,12 @@
/**CFile****************************************************************
- FileName [giaPolyn.c]
+ FileName [acecPolyn.c]
SystemName [ABC: Logic synthesis and verification system.]
- PackageName [Scalable AIG package.]
+ PackageName [CEC for arithmetic circuits.]
- Synopsis [Polynomial manipulation.]
+ Synopsis [Polynomial extraction.]
Author [Alan Mishchenko]
@@ -14,11 +14,11 @@
Date [Ver. 1.0. Started - June 20, 2005.]
- Revision [$Id: giaPolyn.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+ Revision [$Id: acecPolyn.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
-#include "gia.h"
+#include "acecInt.h"
#include "misc/vec/vecWec.h"
#include "misc/vec/vecHsh.h"
#include "misc/vec/vecQue.h"
@@ -40,188 +40,8 @@ MUX(a, b, c) -> ab | (1 - a)c = ab + (1-a)c - ab(1-a)c = ab + c - ac
!a & b -> (1 - a)b = b - ab
a & !b -> a(1 - b) = a - ab
!a & !b -> 1 - a - b + ab
-!(a & b) -> 1 - ab
*/
-////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFINITIONS ///
-////////////////////////////////////////////////////////////////////////
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Gia_PolynAddNew( Hsh_VecMan_t * pHash, Vec_Int_t * vCoef, int Coef, Vec_Int_t * vProd, Vec_Wec_t * vMap )
-{
- int i, Lit, Value;
- //Vec_IntPrint( vProd );
-
- Value = Hsh_VecManAdd( pHash, vProd );
- if ( Value == Vec_IntSize(vCoef) )
- {
- Vec_IntPush( vCoef, 0 );
- Vec_IntForEachEntry( vProd, Lit, i )
- Vec_WecPush( vMap, Abc_Lit2Var(Lit), Value );
- }
- assert( Value < Vec_IntSize(vCoef) );
- Vec_IntAddToEntry( vCoef, Value, Coef );
-}
-int Gia_PolynTransform1( Hsh_VecMan_t * pHash, Vec_Int_t * vCoef, int Coef, Vec_Int_t * vProd, Vec_Wec_t * vMap, int Id )
-{
- int i, Lit;
- Vec_IntForEachEntry( vProd, Lit, i )
- if ( Abc_Lit2Var(Lit) == Id )
- break;
- assert( i < Vec_IntSize(vProd) );
- if ( !Abc_LitIsCompl(Lit) )
- return 0;
- // update array
- Vec_IntWriteEntry( vProd, i, Abc_LitNot(Lit) );
- Gia_PolynAddNew( pHash, vCoef, Coef, vProd, vMap );
- Vec_IntWriteEntry( vProd, i, Lit );
- return 1;
-}
-void Gia_PolynTransform( Hsh_VecMan_t * pHash, Vec_Int_t * vCoef, int Coef, Vec_Int_t * vProd, Vec_Wec_t * vMap, int Id, int Lit0, int Lit1, Vec_Int_t * vTemp )
-{
- int pArray[2] = { Lit0, Lit1 };
- Vec_Int_t vTwo = { 2, 2, pArray };
-
- int Var0 = Abc_Lit2Var( Lit0 );
- int Var1 = Abc_Lit2Var( Lit1 );
- int i, Lit = Vec_IntPop(vProd);
-
- assert( Abc_Lit2Var(Lit) == Id );
- if ( Abc_LitIsCompl(Lit) )
- {
- Gia_PolynAddNew( pHash, vCoef, Coef, vProd, vMap );
- Coef = -Coef;
- }
-
- assert( Var0 < Var1 );
- Vec_IntForEachEntry( vProd, Lit, i )
- if ( Abc_LitNot(Lit) == Lit0 || Abc_LitNot(Lit) == Lit1 )
- return;
- assert( Vec_IntCap(vTemp) >= Vec_IntSize(vTemp) + 2 );
-
- // merge inputs
- Vec_IntTwoMerge2Int( vProd, &vTwo, vTemp );
-/*
- printf( "\n" );
- Vec_IntPrint( vProd );
- Vec_IntPrint( &vTwo );
- Vec_IntPrint( vTemp );
- printf( "\n" );
-*/
- // create new
- Gia_PolynAddNew( pHash, vCoef, Coef, vTemp, vMap );
-}
-int Gia_PolynPrint( Hsh_VecMan_t * pHash, Vec_Int_t * vCoef )
-{
- Vec_Int_t * vProd;
- int Value, Coef, Lit, i, Count = 0;
- Vec_IntForEachEntry( vCoef, Coef, Value )
- {
- if ( Coef == 0 )
- continue;
- vProd = Hsh_VecReadEntry( pHash, Value );
- printf( "(%d)", Coef );
- Vec_IntForEachEntry( vProd, Lit, i )
- printf( "*%d", Lit );
- printf( " " );
- Count++;
- }
- printf( "\n" );
- return Count;
-}
-void Gia_PolynTest( Gia_Man_t * pGia )
-{
- Hsh_VecMan_t * pHash = Hsh_VecManStart( 1000000 );
- Vec_Int_t * vCoef = Vec_IntAlloc( 1000000 );
- Vec_Wec_t * vMap = Vec_WecStart( Gia_ManObjNum(pGia) );
- Vec_Int_t * vTemp = Vec_IntAlloc( 100000 );
- Vec_Int_t * vThisOne, * vProd;
- Gia_Obj_t * pObj;
- int i, k, Value, Coef, Count;
- abctime clk = Abc_Clock();
-
- assert( Gia_ManPoNum(pGia) < 32 );
-
- // add constant
- Value = Hsh_VecManAdd( pHash, vTemp );
- assert( Value == 0 );
- Vec_IntPush( vCoef, 0 );
-
- // start the outputs
- Gia_ManForEachPo( pGia, pObj, i )
- {
- assert( Gia_ObjFaninId0p(pGia, pObj) > 0 );
- Vec_IntFill( vTemp, 1, Gia_ObjFaninLit0p(pGia, pObj) );
- Value = Hsh_VecManAdd( pHash, vTemp );
- //assert( Value == i + 1 );
- Vec_IntPush( vCoef, 1 << i );
- Vec_WecPush( vMap, Gia_ObjFaninId0p(pGia, pObj), Value );
- }
- assert( Vec_IntSize(vCoef) == Hsh_VecSize(pHash) );
-
- Gia_PolynPrint( pHash, vCoef );
-
- // substitute
- Gia_ManForEachAndReverse( pGia, pObj, i )
- {
- vThisOne = Vec_WecEntry( vMap, i );
- assert( Vec_IntSize(vThisOne) > 0 );
- Vec_IntForEachEntry( vThisOne, Value, k )
- {
- vProd = Hsh_VecReadEntry( pHash, Value );
- Coef = Vec_IntEntry( vCoef, Value );
- if ( Coef == 0 )
- continue;
- Gia_PolynTransform( pHash, vCoef, Coef, vProd, vMap, i, Gia_ObjFaninLit0p(pGia, pObj), Gia_ObjFaninLit1p(pGia, pObj), vTemp );
- Vec_IntWriteEntry( vCoef, Value, 0 );
- }
- Vec_IntErase( vThisOne );
- }
-
- // inputs
- Gia_ManForEachCiReverse( pGia, pObj, i )
- {
- vThisOne = Vec_WecEntry( vMap, Gia_ObjId(pGia, pObj) );
- if ( Vec_IntSize(vThisOne) == 0 )
- continue;
- assert( Vec_IntSize(vThisOne) > 0 );
- Vec_IntForEachEntry( vThisOne, Value, k )
- {
- vProd = Hsh_VecReadEntry( pHash, Value );
- Coef = Vec_IntEntry( vCoef, Value );
- if ( Coef == 0 )
- continue;
- if ( Gia_PolynTransform1( pHash, vCoef, Coef, vProd, vMap, Gia_ObjId(pGia, pObj) ) )
- Vec_IntWriteEntry( vCoef, Value, 0 );
- }
- Vec_IntErase( vThisOne );
- }
-
- Count = Gia_PolynPrint( pHash, vCoef );
- printf( "Entries = %d. Useful = %d. ", Vec_IntSize(vCoef), Count );
- Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
-
- Hsh_VecManStop( pHash );
- Vec_IntFree( vCoef );
- Vec_WecFree( vMap );
- Vec_IntFree( vTemp );
-}
-
-
-
-
-
typedef struct Pln_Man_t_ Pln_Man_t;
struct Pln_Man_t_
{
@@ -233,9 +53,16 @@ struct Pln_Man_t_
Vec_Int_t * vCoefs; // coefficients for each monomial
Vec_Int_t * vTempC[2]; // polynomial representation
Vec_Int_t * vTempM[4]; // polynomial representation
+ Vec_Int_t * vOrder; // order of collapsing
int nBuilds; // builds
};
-
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+
/**Function*************************************************************
Synopsis [Computation manager.]
@@ -247,7 +74,7 @@ struct Pln_Man_t_
SeeAlso []
***********************************************************************/
-Pln_Man_t * Pln_ManAlloc( Gia_Man_t * pGia )
+Pln_Man_t * Pln_ManAlloc( Gia_Man_t * pGia, Vec_Int_t * vOrder )
{
Pln_Man_t * p = ABC_CALLOC( Pln_Man_t, 1 );
p->pGia = pGia;
@@ -262,6 +89,8 @@ Pln_Man_t * Pln_ManAlloc( Gia_Man_t * pGia )
p->vTempM[1] = Vec_IntAlloc( 100 );
p->vTempM[2] = Vec_IntAlloc( 100 );
p->vTempM[3] = Vec_IntAlloc( 100 );
+ p->vOrder = vOrder ? vOrder : Vec_IntStartNatural( Gia_ManObjNum(pGia) );
+ assert( Vec_IntSize(p->vOrder) == Gia_ManObjNum(pGia) );
Vec_QueSetPriority( p->vQue, Vec_FltArrayP(p->vCounts) );
// add 0-constant and 1-monomial
Hsh_VecManAdd( p->pHashC, p->vTempC[0] );
@@ -283,6 +112,7 @@ void Pln_ManStop( Pln_Man_t * p )
Vec_IntFree( p->vTempM[1] );
Vec_IntFree( p->vTempM[2] );
Vec_IntFree( p->vTempM[3] );
+ Vec_IntFree( p->vOrder );
ABC_FREE( p );
}
void Pln_ManPrintFinal( Pln_Man_t * p )
@@ -296,12 +126,12 @@ void Pln_ManPrintFinal( Pln_Man_t * p )
Count++;
- if ( Vec_IntSize(p->vCoefs) > 1000 )
+ if ( Count > 40 )
continue;
vArray = Hsh_VecReadEntry( p->pHashC, iConst );
Vec_IntForEachEntry( vArray, Entry, k )
- printf( "%s%s2^%d", k ? " + " : "", Entry < 0 ? "-" : "+", Abc_AbsInt(Entry)-1 );
+ printf( "%s%d", Entry < 0 ? "-" : "+", (1 << (Abc_AbsInt(Entry)-1)) );
vArray = Hsh_VecReadEntry( p->pHashM, iMono );
Vec_IntForEachEntry( vArray, Entry, k )
@@ -368,7 +198,8 @@ static inline void Gia_PolynBuildAdd( Pln_Man_t * p, Vec_Int_t * vTempC, Vec_Int
{
iConst = Hsh_VecManAdd( p->pHashC, vTempC );
Vec_IntPush( p->vCoefs, iConst );
- Vec_FltPush( p->vCounts, Vec_IntEntryLast(vTempM) );
+// Vec_FltPush( p->vCounts, Vec_IntEntryLast(vTempM) );
+ Vec_FltPush( p->vCounts, (float)Vec_IntEntry(p->vOrder, Vec_IntEntryLast(vTempM)) );
Vec_QuePush( p->vQue, iMono );
// Vec_QueUpdate( p->vQue, iMono );
return;
@@ -407,9 +238,11 @@ void Gia_PolynBuildOne( Pln_Man_t * p, int iMono )
Vec_IntAppend( p->vTempM[k], vArray );
Vec_IntPop( p->vTempM[k] );
if ( k == 1 || k == 3 )
- Vec_IntPushUniqueOrder( p->vTempM[k], iFan0 ); // x
+ Vec_IntPushUniqueOrderCost( p->vTempM[k], iFan0, p->vOrder ); // x
+// Vec_IntPushUniqueOrder( p->vTempM[k], iFan0 ); // x
if ( k == 2 || k == 3 )
- Vec_IntPushUniqueOrder( p->vTempM[k], iFan1 ); // y
+ Vec_IntPushUniqueOrderCost( p->vTempM[k], iFan1, p->vOrder ); // y
+// Vec_IntPushUniqueOrder( p->vTempM[k], iFan1 ); // y
}
vConst = Hsh_VecReadEntry( p->pHashC, iConst );
@@ -468,12 +301,13 @@ int Gia_PolyFindNext( Pln_Man_t * p )
//Vec_IntPrint( Hsh_VecReadEntry(p->pHashM, iBest) );
return iBest;
}
-void Gia_PolynBuildTest( Gia_Man_t * pGia )
+void Gia_PolynBuild( Gia_Man_t * pGia, Vec_Int_t * vOrder, int fVerbose )
{
abctime clk = Abc_Clock();//, clk2 = 0;
Gia_Obj_t * pObj;
- int i, iMono, iDriver;
- Pln_Man_t * p = Pln_ManAlloc( pGia );
+ Vec_Bit_t * vPres = Vec_BitStart( Gia_ManObjNum(pGia) );
+ int i, iMono, iDriver, LevPrev, LevCur, Iter, Line = 0;
+ Pln_Man_t * p = Pln_ManAlloc( pGia, vOrder );
Gia_ManForEachCoReverse( pGia, pObj, i )
{
Vec_IntFill( p->vTempC[0], 1, i+1 ); // 2^i
@@ -490,12 +324,33 @@ void Gia_PolynBuildTest( Gia_Man_t * pGia )
else
Gia_PolynBuildAdd( p, p->vTempC[0], p->vTempM[0] ); // C * Driver
}
- while ( 1 )
+ LevPrev = -1;
+ for ( Iter = 0; ; Iter++ )
{
+ Vec_Int_t * vTempM;
//abctime temp = Abc_Clock();
iMono = Gia_PolyFindNext(p);
if ( !iMono )
break;
+
+ // report
+ vTempM = Hsh_VecReadEntry( p->pHashM, iMono );
+ //printf( "Removing var %d\n", Vec_IntEntryLast(vTempM) );
+
+// LevCur = Vec_IntEntryLast(vTempM);
+ LevCur = Vec_IntEntry(p->vOrder, Vec_IntEntryLast(vTempM));
+ if ( LevPrev != LevCur )
+ {
+ if ( Vec_BitEntry( vPres, LevCur & 0xFF ) )
+ printf( "Repeating entry %d\n", LevCur & 0xFF );
+ else
+ Vec_BitSetEntry( vPres, LevCur & 0xFF, 1 );
+
+ printf( "Line %5d Iter %6d : Cur = %8x. Obj = %5d. HashC =%8d. HashM =%8d. Total =%8d. Used =%8d.\n",
+ Line++, Iter, LevCur, LevCur & 0xFF, Hsh_VecSize(p->pHashC), Hsh_VecSize(p->pHashM), p->nBuilds, -1 );
+ }
+ LevPrev = LevCur;
+
Gia_PolynBuildOne( p, iMono );
//clk2 += Abc_Clock() - temp;
}
@@ -503,10 +358,10 @@ void Gia_PolynBuildTest( Gia_Man_t * pGia )
//Abc_PrintTime( 1, "Time2", clk2 );
Pln_ManPrintFinal( p );
Pln_ManStop( p );
+ Vec_BitFree( vPres );
}
-
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/proof/acec/acecUtil.c b/src/proof/acec/acecUtil.c
new file mode 100644
index 00000000..26087f92
--- /dev/null
+++ b/src/proof/acec/acecUtil.c
@@ -0,0 +1,87 @@
+/**CFile****************************************************************
+
+ FileName [acecUtil.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [CEC for arithmetic circuits.]
+
+ Synopsis [Various utilities.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: acecUtil.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 Gia_PolynCollectXors_rec( Gia_Man_t * pGia, int iObj, Vec_Int_t * vXors )
+{
+ Gia_Obj_t * pObj = Gia_ManObj( pGia, iObj );
+ if ( Gia_ObjIsTravIdCurrent(pGia, pObj) )
+ return;
+ Gia_ObjSetTravIdCurrent(pGia, pObj);
+ if ( !Gia_ObjIsAnd(pObj) || !Gia_ObjIsXor(pObj) )
+ return;
+ Vec_IntPush( vXors, iObj );
+ Gia_PolynCollectXors_rec( pGia, Gia_ObjFaninId0(pObj, iObj), vXors );
+ Gia_PolynCollectXors_rec( pGia, Gia_ObjFaninId1(pObj, iObj), vXors );
+}
+void Gia_PolynAnalyzeXors( Gia_Man_t * pGia, int fVerbose )
+{
+ int i, iDriver, Count = 0;
+ Vec_Int_t * vXors = Vec_IntAlloc( 100 );
+ if ( pGia->pMuxes == NULL )
+ {
+ printf( "AIG does not have XORs extracted.\n" );
+ return;
+ }
+ assert( pGia->pMuxes );
+ Gia_ManForEachCoDriverId( pGia, iDriver, i )
+ {
+ Vec_IntClear( vXors );
+ Gia_ManIncrementTravId( pGia );
+ Gia_PolynCollectXors_rec( pGia, iDriver, vXors );
+ //printf( "%3d : ", i );
+ //Vec_IntPrint( vXors );
+ printf( "%d=%d ", i, Vec_IntSize(vXors) );
+ Count += Vec_IntSize(vXors);
+ }
+ printf( "Total = %d.\n", Count );
+ Vec_IntFree( vXors );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/proof/acec/module.make b/src/proof/acec/module.make
new file mode 100644
index 00000000..20da6358
--- /dev/null
+++ b/src/proof/acec/module.make
@@ -0,0 +1,5 @@
+SRC += src/proof/acec/acecCore. \
+ src/proof/acec/acecFadds.c \
+ src/proof/acec/acecOrder.c \
+ src/proof/acec/acecPolyn.c \
+ src/proof/acec/acecUtil.c