summaryrefslogtreecommitdiffstats
path: root/src/proof/llb/llb4Nonlin.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2015-08-24 21:09:50 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2015-08-24 21:09:50 -0700
commit24f2a120f2203acc8038ccce4e8dd141564a7a04 (patch)
treed8c0d0efa6c2dc1ef656624f807ba3f4f6db8b9d /src/proof/llb/llb4Nonlin.c
parenteb699bbaf80e4a6a0e85f87d7575ca1ffebef37f (diff)
downloadabc-24f2a120f2203acc8038ccce4e8dd141564a7a04.tar.gz
abc-24f2a120f2203acc8038ccce4e8dd141564a7a04.tar.bz2
abc-24f2a120f2203acc8038ccce4e8dd141564a7a04.zip
Changes to be able to compile ABC without CUDD.
Diffstat (limited to 'src/proof/llb/llb4Nonlin.c')
-rw-r--r--src/proof/llb/llb4Nonlin.c1185
1 files changed, 0 insertions, 1185 deletions
diff --git a/src/proof/llb/llb4Nonlin.c b/src/proof/llb/llb4Nonlin.c
deleted file mode 100644
index a9421358..00000000
--- a/src/proof/llb/llb4Nonlin.c
+++ /dev/null
@@ -1,1185 +0,0 @@
-/**CFile****************************************************************
-
- FileName [llb2Nonlin.c]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [BDD based reachability.]
-
- Synopsis [Non-linear quantification scheduling.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: llb2Nonlin.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-#include "llbInt.h"
-#include "base/abc/abc.h"
-#include "aig/gia/giaAig.h"
-
-ABC_NAMESPACE_IMPL_START
-
-
-////////////////////////////////////////////////////////////////////////
-/// DECLARATIONS ///
-////////////////////////////////////////////////////////////////////////
-
-typedef struct Llb_Mnx_t_ Llb_Mnx_t;
-struct Llb_Mnx_t_
-{
- // user info
- Aig_Man_t * pAig; // AIG manager
- Gia_ParLlb_t * pPars; // parameters
-
- // intermediate BDDs
- DdManager * dd; // BDD manager
- DdNode * bBad; // bad states in terms of CIs
- DdNode * bReached; // reached states
- DdNode * bCurrent; // from states
- DdNode * bNext; // to states
- Vec_Ptr_t * vRings; // onion rings in ddR
- Vec_Ptr_t * vRoots; // BDDs for partitions
-
- // structural info
- Vec_Int_t * vOrder; // for each object ID, its BDD variable number or -1
- Vec_Int_t * vVars2Q; // 1 if variable is quantifiable; 0 othervise
-
- abctime timeImage;
- abctime timeRemap;
- abctime timeReo;
- abctime timeOther;
- abctime timeTotal;
-};
-
-//extern int timeBuild, timeAndEx, timeOther;
-//extern int nSuppMax;
-
-////////////////////////////////////////////////////////////////////////
-/// FUNCTION DEFINITIONS ///
-////////////////////////////////////////////////////////////////////////
-
-/**Function*************************************************************
-
- Synopsis [Computes bad in working manager.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Llb_Nonlin4ComputeBad( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder )
-{
- Vec_Ptr_t * vNodes;
- DdNode * bBdd, * bBdd0, * bBdd1, * bTemp, * bResult, * bCube;
- Aig_Obj_t * pObj;
- int i;
- Aig_ManCleanData( pAig );
- // assign elementary variables
- Aig_ManConst1(pAig)->pData = Cudd_ReadOne(dd);
- Aig_ManForEachCi( pAig, pObj, i )
- pObj->pData = Cudd_bddIthVar( dd, Llb_ObjBddVar(vOrder, pObj) );
- // compute internal nodes
- vNodes = Aig_ManDfsNodes( pAig, (Aig_Obj_t **)Vec_PtrArray(pAig->vCos), Saig_ManPoNum(pAig) );
- Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
- {
- if ( !Aig_ObjIsNode(pObj) )
- continue;
- bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) );
- bBdd1 = Cudd_NotCond( (DdNode *)Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) );
- bBdd = Cudd_bddAnd( dd, bBdd0, bBdd1 );
- if ( bBdd == NULL )
- {
- Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
- if ( Aig_ObjIsNode(pObj) && pObj->pData != NULL )
- Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData );
- Vec_PtrFree( vNodes );
- return NULL;
- }
- Cudd_Ref( bBdd );
- pObj->pData = bBdd;
- }
- // quantify PIs of each PO
- bResult = Cudd_ReadLogicZero( dd ); Cudd_Ref( bResult );
- Saig_ManForEachPo( pAig, pObj, i )
- {
- bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) );
- bResult = Cudd_bddOr( dd, bTemp = bResult, bBdd0 );
- if ( bResult == NULL )
- {
- Cudd_RecursiveDeref( dd, bTemp );
- break;
- }
- Cudd_Ref( bResult );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- // deref
- Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
- if ( Aig_ObjIsNode(pObj) && pObj->pData != NULL )
- Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData );
- Vec_PtrFree( vNodes );
- if ( bResult )
- {
- bCube = Cudd_ReadOne(dd); Cudd_Ref( bCube );
- Saig_ManForEachPi( pAig, pObj, i )
- {
- bCube = Cudd_bddAnd( dd, bTemp = bCube, (DdNode *)pObj->pData );
- if ( bCube == NULL )
- {
- Cudd_RecursiveDeref( dd, bTemp );
- Cudd_RecursiveDeref( dd, bResult );
- bResult = NULL;
- break;
- }
- Cudd_Ref( bCube );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- if ( bResult != NULL )
- {
- bResult = Cudd_bddExistAbstract( dd, bTemp = bResult, bCube ); Cudd_Ref( bResult );
- Cudd_RecursiveDeref( dd, bTemp );
- Cudd_RecursiveDeref( dd, bCube );
- Cudd_Deref( bResult );
- }
- }
-//if ( bResult )
-//printf( "Bad state = %d.\n", Cudd_DagSize(bResult) );
- return bResult;
-}
-
-/**Function*************************************************************
-
- Synopsis [Derives BDDs for the partitions.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_Nonlin4DerivePartitions( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder )
-{
- Vec_Ptr_t * vRoots;
- Aig_Obj_t * pObj;
- DdNode * bBdd, * bBdd0, * bBdd1, * bPart;
- int i;
- Aig_ManCleanData( pAig );
- // assign elementary variables
- Aig_ManConst1(pAig)->pData = Cudd_ReadOne(dd);
- Aig_ManForEachCi( pAig, pObj, i )
- pObj->pData = Cudd_bddIthVar( dd, Llb_ObjBddVar(vOrder, pObj) );
- Aig_ManForEachNode( pAig, pObj, i )
- if ( Llb_ObjBddVar(vOrder, pObj) >= 0 )
- {
- pObj->pData = Cudd_bddIthVar( dd, Llb_ObjBddVar(vOrder, pObj) );
- Cudd_Ref( (DdNode *)pObj->pData );
- }
- Saig_ManForEachLi( pAig, pObj, i )
- pObj->pData = Cudd_bddIthVar( dd, Llb_ObjBddVar(vOrder, pObj) );
- // compute intermediate BDDs
- vRoots = Vec_PtrAlloc( 100 );
- Aig_ManForEachNode( pAig, pObj, i )
- {
- bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) );
- bBdd1 = Cudd_NotCond( (DdNode *)Aig_ObjFanin1(pObj)->pData, Aig_ObjFaninC1(pObj) );
- bBdd = Cudd_bddAnd( dd, bBdd0, bBdd1 );
- if ( bBdd == NULL )
- goto finish;
- Cudd_Ref( bBdd );
- if ( pObj->pData == NULL )
- {
- pObj->pData = bBdd;
- continue;
- }
- // create new partition
- bPart = Cudd_bddXnor( dd, (DdNode *)pObj->pData, bBdd );
- if ( bPart == NULL )
- goto finish;
- Cudd_Ref( bPart );
- Cudd_RecursiveDeref( dd, bBdd );
- Vec_PtrPush( vRoots, bPart );
-//printf( "%d ", Cudd_DagSize(bPart) );
- }
- // compute register output BDDs
- Saig_ManForEachLi( pAig, pObj, i )
- {
- bBdd0 = Cudd_NotCond( (DdNode *)Aig_ObjFanin0(pObj)->pData, Aig_ObjFaninC0(pObj) );
- bPart = Cudd_bddXnor( dd, (DdNode *)pObj->pData, bBdd0 );
- if ( bPart == NULL )
- goto finish;
- Cudd_Ref( bPart );
- Vec_PtrPush( vRoots, bPart );
-//printf( "%d ", Cudd_DagSize(bPart) );
- }
-//printf( "\n" );
- Aig_ManForEachNode( pAig, pObj, i )
- Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData );
- return vRoots;
- // early termination
-finish:
- Aig_ManForEachNode( pAig, pObj, i )
- if ( pObj->pData )
- Cudd_RecursiveDeref( dd, (DdNode *)pObj->pData );
- Vec_PtrForEachEntry( DdNode *, vRoots, bPart, i )
- Cudd_RecursiveDeref( dd, bPart );
- Vec_PtrFree( vRoots );
- return NULL;
-}
-
-/**Function*************************************************************
-
- Synopsis [Find simple variable ordering.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Int_t * Llb_Nonlin4CreateOrderSimple( Aig_Man_t * pAig )
-{
- Vec_Int_t * vOrder;
- Aig_Obj_t * pObj;
- int i, Counter = 0;
- vOrder = Vec_IntStartFull( Aig_ManObjNumMax(pAig) );
- Aig_ManForEachCi( pAig, pObj, i )
- Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), Counter++ );
- Saig_ManForEachLi( pAig, pObj, i )
- Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), Counter++ );
- return vOrder;
-}
-
-/**Function*************************************************************
-
- Synopsis [Find good static variable ordering.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_Nonlin4CreateOrder_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Int_t * vOrder, int * pCounter )
-{
- Aig_Obj_t * pFanin0, * pFanin1;
- if ( Aig_ObjIsTravIdCurrent(pAig, pObj) )
- return;
- Aig_ObjSetTravIdCurrent( pAig, pObj );
- assert( Llb_ObjBddVar(vOrder, pObj) < 0 );
- if ( Aig_ObjIsCi(pObj) )
- {
-// if ( Saig_ObjIsLo(pAig, pObj) )
-// Vec_IntWriteEntry( vOrder, Aig_ObjId(Saig_ObjLoToLi(pAig, pObj)), (*pCounter)++ );
- Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), (*pCounter)++ );
- return;
- }
- // try fanins with higher level first
- pFanin0 = Aig_ObjFanin0(pObj);
- pFanin1 = Aig_ObjFanin1(pObj);
-// if ( pFanin0->Level > pFanin1->Level || (pFanin0->Level == pFanin1->Level && pFanin0->Id < pFanin1->Id) )
- if ( pFanin0->Level > pFanin1->Level )
- {
- Llb_Nonlin4CreateOrder_rec( pAig, pFanin0, vOrder, pCounter );
- Llb_Nonlin4CreateOrder_rec( pAig, pFanin1, vOrder, pCounter );
- }
- else
- {
- Llb_Nonlin4CreateOrder_rec( pAig, pFanin1, vOrder, pCounter );
- Llb_Nonlin4CreateOrder_rec( pAig, pFanin0, vOrder, pCounter );
- }
- if ( pObj->fMarkA )
- Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), (*pCounter)++ );
-}
-
-/**Function*************************************************************
-
- Synopsis [Collect nodes with the given fanout count.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Int_t * Llb_Nonlin4CollectHighRefNodes( Aig_Man_t * pAig, int nFans )
-{
- Vec_Int_t * vNodes;
- Aig_Obj_t * pObj;
- int i;
- Aig_ManCleanMarkA( pAig );
- Aig_ManForEachNode( pAig, pObj, i )
- if ( Aig_ObjRefs(pObj) >= nFans )
- pObj->fMarkA = 1;
- // unmark flop drivers
- Saig_ManForEachLi( pAig, pObj, i )
- Aig_ObjFanin0(pObj)->fMarkA = 0;
- // collect mapping
- vNodes = Vec_IntAlloc( 100 );
- Aig_ManForEachNode( pAig, pObj, i )
- if ( pObj->fMarkA )
- Vec_IntPush( vNodes, Aig_ObjId(pObj) );
- Aig_ManCleanMarkA( pAig );
- return vNodes;
-}
-
-/**Function*************************************************************
-
- Synopsis [Find good static variable ordering.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Int_t * Llb_Nonlin4CreateOrder( Aig_Man_t * pAig )
-{
- Vec_Int_t * vNodes = NULL;
- Vec_Int_t * vOrder;
- Aig_Obj_t * pObj;
- int i, Counter = 0;
-/*
- // mark internal nodes to be used
- Aig_ManCleanMarkA( pAig );
- vNodes = Llb_Nonlin4CollectHighRefNodes( pAig, 4 );
- Aig_ManForEachObjVec( vNodes, pAig, pObj, i )
- pObj->fMarkA = 1;
-printf( "Techmapping added %d pivots.\n", Vec_IntSize(vNodes) );
-*/
- // collect nodes in the order
- vOrder = Vec_IntStartFull( Aig_ManObjNumMax(pAig) );
- Aig_ManIncrementTravId( pAig );
- Aig_ObjSetTravIdCurrent( pAig, Aig_ManConst1(pAig) );
- Saig_ManForEachLi( pAig, pObj, i )
- {
- Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), Counter++ );
- Llb_Nonlin4CreateOrder_rec( pAig, Aig_ObjFanin0(pObj), vOrder, &Counter );
- }
- Aig_ManForEachCi( pAig, pObj, i )
- if ( Llb_ObjBddVar(vOrder, pObj) < 0 )
- {
-// if ( Saig_ObjIsLo(pAig, pObj) )
-// Vec_IntWriteEntry( vOrder, Aig_ObjId(Saig_ObjLoToLi(pAig, pObj)), Counter++ );
- Vec_IntWriteEntry( vOrder, Aig_ObjId(pObj), Counter++ );
- }
- assert( Counter <= Aig_ManCiNum(pAig) + Aig_ManRegNum(pAig) + (vNodes?Vec_IntSize(vNodes):0) );
- Aig_ManCleanMarkA( pAig );
- Vec_IntFreeP( &vNodes );
- return vOrder;
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Creates quantifiable varaibles for both types of traversal.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Int_t * Llb_Nonlin4CreateVars2Q( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder, int fBackward )
-{
- Vec_Int_t * vVars2Q;
- Aig_Obj_t * pObjLi, * pObjLo;
- int i;
- vVars2Q = Vec_IntAlloc( 0 );
- Vec_IntFill( vVars2Q, Cudd_ReadSize(dd), 1 );
- Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i )
- Vec_IntWriteEntry( vVars2Q, Llb_ObjBddVar(vOrder, fBackward ? pObjLo : pObjLi), 0 );
- return vVars2Q;
-}
-
-/**Function*************************************************************
-
- Synopsis [Compute initial state in terms of current state variables.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_Nonlin4SetupVarMap( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder )
-{
- DdNode ** pVarsX, ** pVarsY;
- Aig_Obj_t * pObjLo, * pObjLi;
- int i;
- pVarsX = ABC_ALLOC( DdNode *, Cudd_ReadSize(dd) );
- pVarsY = ABC_ALLOC( DdNode *, Cudd_ReadSize(dd) );
- Saig_ManForEachLiLo( pAig, pObjLo, pObjLi, i )
- {
- assert( Llb_ObjBddVar(vOrder, pObjLo) >= 0 );
- assert( Llb_ObjBddVar(vOrder, pObjLi) >= 0 );
- pVarsX[i] = Cudd_bddIthVar( dd, Llb_ObjBddVar(vOrder, pObjLo) );
- pVarsY[i] = Cudd_bddIthVar( dd, Llb_ObjBddVar(vOrder, pObjLi) );
- }
- Cudd_SetVarMap( dd, pVarsX, pVarsY, Aig_ManRegNum(pAig) );
- ABC_FREE( pVarsX );
- ABC_FREE( pVarsY );
-}
-
-/**Function*************************************************************
-
- Synopsis [Compute initial state in terms of current state variables.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Llb_Nonlin4ComputeInitState( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder, int fBackward )
-{
- Aig_Obj_t * pObjLi, * pObjLo;
- DdNode * bRes, * bVar, * bTemp;
- int i;
- abctime TimeStop;
- TimeStop = dd->TimeStop; dd->TimeStop = 0;
- bRes = Cudd_ReadOne( dd ); Cudd_Ref( bRes );
- Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i )
- {
- bVar = Cudd_bddIthVar( dd, Llb_ObjBddVar(vOrder, fBackward? pObjLi : pObjLo) );
- bRes = Cudd_bddAnd( dd, bTemp = bRes, Cudd_Not(bVar) ); Cudd_Ref( bRes );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- Cudd_Deref( bRes );
- dd->TimeStop = TimeStop;
- return bRes;
-}
-
-/**Function*************************************************************
-
- Synopsis [Compute initial state in terms of current state variables.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-DdNode * Llb_Nonlin4ComputeCube( DdManager * dd, Aig_Man_t * pAig, Vec_Int_t * vOrder, char * pValues, int Flag )
-{
- Aig_Obj_t * pObjLo, * pObjLi, * pObjTemp;
- DdNode * bRes, * bVar, * bTemp;
- int i;
- abctime TimeStop;
- TimeStop = dd->TimeStop; dd->TimeStop = 0;
- bRes = Cudd_ReadOne( dd ); Cudd_Ref( bRes );
- Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i )
- {
- if ( Flag )
- pObjTemp = pObjLo, pObjLo = pObjLi, pObjLi = pObjTemp;
- // get the correspoding flop input variable
- bVar = Cudd_bddIthVar( dd, Llb_ObjBddVar(vOrder, pObjLi) );
- if ( pValues[Llb_ObjBddVar(vOrder, pObjLo)] != 1 )
- bVar = Cudd_Not(bVar);
- // create cube
- bRes = Cudd_bddAnd( dd, bTemp = bRes, bVar ); Cudd_Ref( bRes );
- Cudd_RecursiveDeref( dd, bTemp );
- }
- Cudd_Deref( bRes );
- dd->TimeStop = TimeStop;
- return bRes;
-}
-
-/**Function*************************************************************
-
- Synopsis [Compute initial state in terms of current state variables.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_Nonlin4RecordState( Aig_Man_t * pAig, Vec_Int_t * vOrder, unsigned * pState, char * pValues, int fBackward )
-{
- Aig_Obj_t * pObjLo, * pObjLi;
- int i;
- Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i )
- if ( pValues[Llb_ObjBddVar(vOrder, fBackward? pObjLi : pObjLo)] == 1 )
- Abc_InfoSetBit( pState, i );
-}
-
-/**Function*************************************************************
-
- Synopsis [Multiply every partition by the cube.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_Nonlin4Multiply( DdManager * dd, DdNode * bCube, Vec_Ptr_t * vParts )
-{
- Vec_Ptr_t * vNew;
- DdNode * bTemp, * bFunc;
- int i;
- vNew = Vec_PtrAlloc( Vec_PtrSize(vParts) );
- Vec_PtrForEachEntry( DdNode *, vParts, bFunc, i )
- {
- bTemp = Cudd_bddAnd( dd, bFunc, bCube ); Cudd_Ref( bTemp );
- Vec_PtrPush( vNew, bTemp );
- }
- return vNew;
-}
-
-/**Function*************************************************************
-
- Synopsis [Multiply every partition by the cube.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_Nonlin4Deref( DdManager * dd, Vec_Ptr_t * vParts )
-{
- DdNode * bFunc;
- int i;
- Vec_PtrForEachEntry( DdNode *, vParts, bFunc, i )
- Cudd_RecursiveDeref( dd, bFunc );
- Vec_PtrFree( vParts );
-}
-
-/**Function*************************************************************
-
- Synopsis [Derives counter-example by backward reachability.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Vec_Ptr_t * Llb_Nonlin4DeriveCex( Llb_Mnx_t * p, int fBackward, int fVerbose )
-{
- Vec_Int_t * vVars2Q;
- Vec_Ptr_t * vStates, * vRootsNew;
- Aig_Obj_t * pObj;
- DdNode * bState = NULL, * bImage, * bOneCube, * bRing;
- int i, v, RetValue;//, clk = Abc_Clock();
- char * pValues;
- assert( Vec_PtrSize(p->vRings) > 0 );
- // disable the timeout
- p->dd->TimeStop = 0;
-
- // start the state set
- vStates = Vec_PtrAllocSimInfo( Vec_PtrSize(p->vRings), Abc_BitWordNum(Aig_ManRegNum(p->pAig)) );
- Vec_PtrCleanSimInfo( vStates, 0, Abc_BitWordNum(Aig_ManRegNum(p->pAig)) );
- if ( fBackward )
- Vec_PtrReverseOrder( vStates );
-
- // get the last cube
- pValues = ABC_ALLOC( char, Cudd_ReadSize(p->dd) );
- bOneCube = Cudd_bddIntersect( p->dd, (DdNode *)Vec_PtrEntryLast(p->vRings), p->bBad ); Cudd_Ref( bOneCube );
- RetValue = Cudd_bddPickOneCube( p->dd, bOneCube, pValues );
- Cudd_RecursiveDeref( p->dd, bOneCube );
- assert( RetValue );
-
- // record the cube
- Llb_Nonlin4RecordState( p->pAig, p->vOrder, (unsigned *)Vec_PtrEntryLast(vStates), pValues, fBackward );
-
- // write state in terms of NS variables
- if ( Vec_PtrSize(p->vRings) > 1 )
- {
- bState = Llb_Nonlin4ComputeCube( p->dd, p->pAig, p->vOrder, pValues, fBackward ); Cudd_Ref( bState );
- }
- // perform backward analysis
- vVars2Q = Llb_Nonlin4CreateVars2Q( p->dd, p->pAig, p->vOrder, !fBackward );
- Vec_PtrForEachEntryReverse( DdNode *, p->vRings, bRing, v )
- {
- if ( v == Vec_PtrSize(p->vRings) - 1 )
- continue;
-
- // preprocess partitions
- vRootsNew = Llb_Nonlin4Multiply( p->dd, bState, p->vRoots );
- Cudd_RecursiveDeref( p->dd, bState );
-
- // compute the next states
- bImage = Llb_Nonlin4Image( p->dd, vRootsNew, NULL, vVars2Q ); Cudd_Ref( bImage );
- Llb_Nonlin4Deref( p->dd, vRootsNew );
-
- // intersect with the previous set
- bOneCube = Cudd_bddIntersect( p->dd, bImage, bRing ); Cudd_Ref( bOneCube );
- Cudd_RecursiveDeref( p->dd, bImage );
-
- // find any assignment of the BDD
- RetValue = Cudd_bddPickOneCube( p->dd, bOneCube, pValues );
- Cudd_RecursiveDeref( p->dd, bOneCube );
- assert( RetValue );
-
- // record the cube
- Llb_Nonlin4RecordState( p->pAig, p->vOrder, (unsigned *)Vec_PtrEntry(vStates, v), pValues, fBackward );
-
- // check that we get the init state
- if ( v == 0 )
- {
- Saig_ManForEachLo( p->pAig, pObj, i )
- assert( fBackward || pValues[Llb_ObjBddVar(p->vOrder, pObj)] == 0 );
- break;
- }
-
- // write state in terms of NS variables
- bState = Llb_Nonlin4ComputeCube( p->dd, p->pAig, p->vOrder, pValues, fBackward ); Cudd_Ref( bState );
- }
- Vec_IntFree( vVars2Q );
- ABC_FREE( pValues );
- if ( fBackward )
- Vec_PtrReverseOrder( vStates );
-// if ( fVerbose )
-// Abc_PrintTime( 1, "BDD-based cex generation time", Abc_Clock() - clk );
- return vStates;
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Perform reachability with hints.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Llb_Nonlin4Reachability( Llb_Mnx_t * p )
-{
- DdNode * bAux;
- int nIters, nBddSizeFr = 0, nBddSizeTo = 0, nBddSizeTo2 = 0;
- abctime clkTemp, clkIter, clk = Abc_Clock();
- assert( Aig_ManRegNum(p->pAig) > 0 );
-
- if ( p->pPars->fBackward )
- {
- // create bad state in the ring manager
- if ( !p->pPars->fSkipOutCheck )
- {
- p->bBad = Llb_Nonlin4ComputeInitState( p->dd, p->pAig, p->vOrder, p->pPars->fBackward ); Cudd_Ref( p->bBad );
- }
- // create init state
- if ( p->pPars->fCluster )
- p->bCurrent = p->dd->bFunc, p->dd->bFunc = NULL;
- else
- {
- p->bCurrent = Llb_Nonlin4ComputeBad( p->dd, p->pAig, p->vOrder );
- if ( p->bCurrent == NULL )
- {
- if ( !p->pPars->fSilent )
- printf( "Reached timeout (%d seconds) during constructing the bad states.\n", p->pPars->TimeLimit );
- p->pPars->iFrame = -1;
- return -1;
- }
- Cudd_Ref( p->bCurrent );
- }
- // remap into the next states
- p->bCurrent = Cudd_bddVarMap( p->dd, bAux = p->bCurrent );
- if ( p->bCurrent == NULL )
- {
- if ( !p->pPars->fSilent )
- printf( "Reached timeout (%d seconds) during remapping bad states.\n", p->pPars->TimeLimit );
- Cudd_RecursiveDeref( p->dd, bAux );
- p->pPars->iFrame = -1;
- return -1;
- }
- Cudd_Ref( p->bCurrent );
- Cudd_RecursiveDeref( p->dd, bAux );
- }
- else
- {
- // create bad state in the ring manager
- if ( !p->pPars->fSkipOutCheck )
- {
- if ( p->pPars->fCluster )
- p->bBad = p->dd->bFunc, p->dd->bFunc = NULL;
- else
- {
- p->bBad = Llb_Nonlin4ComputeBad( p->dd, p->pAig, p->vOrder );
- if ( p->bBad == NULL )
- {
- if ( !p->pPars->fSilent )
- printf( "Reached timeout (%d seconds) during constructing the bad states.\n", p->pPars->TimeLimit );
- p->pPars->iFrame = -1;
- return -1;
- }
- Cudd_Ref( p->bBad );
- }
- }
- else if ( p->dd->bFunc )
- Cudd_RecursiveDeref( p->dd, p->dd->bFunc ), p->dd->bFunc = NULL;
- // compute the starting set of states
- p->bCurrent = Llb_Nonlin4ComputeInitState( p->dd, p->pAig, p->vOrder, p->pPars->fBackward ); Cudd_Ref( p->bCurrent );
- }
- // perform iterations
- p->bReached = p->bCurrent; Cudd_Ref( p->bReached );
- for ( nIters = 0; nIters < p->pPars->nIterMax; nIters++ )
- {
- clkIter = Abc_Clock();
- // check the runtime limit
- if ( p->pPars->TimeLimit && Abc_Clock() > p->pPars->TimeTarget )
- {
- if ( !p->pPars->fSilent )
- printf( "Reached timeout (%d seconds) during image computation.\n", p->pPars->TimeLimit );
- p->pPars->iFrame = nIters - 1;
- return -1;
- }
-
- // save the onion ring
- Vec_PtrPush( p->vRings, p->bCurrent ); Cudd_Ref( p->bCurrent );
-
- // check it for bad states
- if ( !p->pPars->fSkipOutCheck && !Cudd_bddLeq( p->dd, p->bCurrent, Cudd_Not(p->bBad) ) )
- {
- Vec_Ptr_t * vStates;
- assert( p->pAig->pSeqModel == NULL );
- vStates = Llb_Nonlin4DeriveCex( p, p->pPars->fBackward, p->pPars->fVerbose );
- p->pAig->pSeqModel = Llb4_Nonlin4TransformCex( p->pAig, vStates, -1, p->pPars->fVerbose );
- Vec_PtrFreeP( &vStates );
- if ( !p->pPars->fSilent )
- {
- Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. ", p->pAig->pSeqModel->iPo, p->pAig->pName, nIters );
- Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
- }
- p->pPars->iFrame = nIters - 1;
- return 0;
- }
-
- // compute the next states
- clkTemp = Abc_Clock();
- p->bNext = Llb_Nonlin4Image( p->dd, p->vRoots, p->bCurrent, p->vVars2Q );
- if ( p->bNext == NULL )
- {
- if ( !p->pPars->fSilent )
- printf( "Reached timeout (%d seconds) during image computation in quantification.\n", p->pPars->TimeLimit );
- p->pPars->iFrame = nIters - 1;
- return -1;
- }
- Cudd_Ref( p->bNext );
- p->timeImage += Abc_Clock() - clkTemp;
-
- // remap into current states
- clkTemp = Abc_Clock();
- p->bNext = Cudd_bddVarMap( p->dd, bAux = p->bNext );
- if ( p->bNext == NULL )
- {
- if ( !p->pPars->fSilent )
- printf( "Reached timeout (%d seconds) during remapping next states.\n", p->pPars->TimeLimit );
- Cudd_RecursiveDeref( p->dd, bAux );
- p->pPars->iFrame = nIters - 1;
- return -1;
- }
- Cudd_Ref( p->bNext );
- Cudd_RecursiveDeref( p->dd, bAux );
- p->timeRemap += Abc_Clock() - clkTemp;
-
- // collect statistics
- if ( p->pPars->fVerbose )
- {
- nBddSizeFr = Cudd_DagSize( p->bCurrent );
- nBddSizeTo = Cudd_DagSize( bAux );
- nBddSizeTo2 = Cudd_DagSize( p->bNext );
- }
- Cudd_RecursiveDeref( p->dd, p->bCurrent ); p->bCurrent = NULL;
-
- // derive new states
- p->bCurrent = Cudd_bddAnd( p->dd, p->bNext, Cudd_Not(p->bReached) );
- if ( p->bCurrent == NULL )
- {
- if ( !p->pPars->fSilent )
- printf( "Reached timeout (%d seconds) during image computation in transfer 1.\n", p->pPars->TimeLimit );
- p->pPars->iFrame = nIters - 1;
- return -1;
- }
- Cudd_Ref( p->bCurrent );
- Cudd_RecursiveDeref( p->dd, p->bNext ); p->bNext = NULL;
- if ( Cudd_IsConstant(p->bCurrent) )
- break;
-/*
- // reduce BDD size using constrain // Cudd_bddRestrict
- p->bCurrent = Cudd_bddRestrict( p->dd, bAux = p->bCurrent, Cudd_Not(p->bReached) );
- Cudd_Ref( p->bCurrent );
-printf( "Before = %d. After = %d.\n", Cudd_DagSize(bAux), Cudd_DagSize(p->bCurrent) );
- Cudd_RecursiveDeref( p->dd, bAux );
-*/
-
- // add to the reached set
- p->bReached = Cudd_bddOr( p->dd, bAux = p->bReached, p->bCurrent );
- if ( p->bReached == NULL )
- {
- if ( !p->pPars->fSilent )
- printf( "Reached timeout (%d seconds) during image computation in transfer 1.\n", p->pPars->TimeLimit );
- p->pPars->iFrame = nIters - 1;
- Cudd_RecursiveDeref( p->dd, bAux );
- return -1;
- }
- Cudd_Ref( p->bReached );
- Cudd_RecursiveDeref( p->dd, bAux );
-
-
- // report the results
- if ( p->pPars->fVerbose )
- {
- printf( "I =%5d : ", nIters );
- printf( "Fr =%7d ", nBddSizeFr );
- printf( "ImNs =%7d ", nBddSizeTo );
- printf( "ImCs =%7d ", nBddSizeTo2 );
- printf( "Rea =%7d ", Cudd_DagSize(p->bReached) );
- printf( "(%4d %4d) ", Cudd_ReadReorderings(p->dd), Cudd_ReadGarbageCollections(p->dd) );
- Abc_PrintTime( 1, "T", Abc_Clock() - clkIter );
- }
-/*
- if ( pPars->fVerbose )
- {
- double nMints = Cudd_CountMinterm(p->dd, bReached, Saig_ManRegNum(p->pAig) );
-// Extra_bddPrint( p->dd, bReached );printf( "\n" );
- printf( "Reachable states = %.0f. (Ratio = %.4f %%)\n", nMints, 100.0*nMints/pow(2.0, Saig_ManRegNum(p->pAig)) );
- fflush( stdout );
- }
-*/
- if ( nIters == p->pPars->nIterMax - 1 )
- {
- if ( !p->pPars->fSilent )
- printf( "Reached limit on the number of timeframes (%d).\n", p->pPars->nIterMax );
- p->pPars->iFrame = nIters;
- return -1;
- }
- }
-
- // report the stats
- if ( p->pPars->fVerbose )
- {
- double nMints = Cudd_CountMinterm(p->dd, p->bReached, Saig_ManRegNum(p->pAig) );
- if ( p->bCurrent && Cudd_IsConstant(p->bCurrent) )
- printf( "Reachability analysis completed after %d frames.\n", nIters );
- else
- printf( "Reachability analysis is stopped after %d frames.\n", nIters );
- printf( "Reachable states = %.0f. (Ratio = %.4f %%)\n", nMints, 100.0*nMints/pow(2.0, Saig_ManRegNum(p->pAig)) );
- fflush( stdout );
- }
- if ( p->bCurrent == NULL || !Cudd_IsConstant(p->bCurrent) )
- {
- if ( !p->pPars->fSilent )
- printf( "Verified only for states reachable in %d frames. ", nIters );
- p->pPars->iFrame = p->pPars->nIterMax;
- return -1; // undecided
- }
- // report
- if ( !p->pPars->fSilent )
- printf( "The miter is proved unreachable after %d iterations. ", nIters );
- if ( !p->pPars->fSilent )
- Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
- p->pPars->iFrame = nIters - 1;
- return 1; // unreachable
-}
-
-/**Function*************************************************************
-
- Synopsis [Reorders BDDs in the working manager.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_Nonlin4Reorder( DdManager * dd, int fTwice, int fVerbose )
-{
- abctime clk = Abc_Clock();
- if ( fVerbose )
- Abc_Print( 1, "Reordering... Before =%5d. ", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
- Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 );
- if ( fVerbose )
- Abc_Print( 1, "After =%5d. ", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
- if ( fTwice )
- {
- Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 );
- if ( fVerbose )
- Abc_Print( 1, "After =%5d. ", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
- }
- if ( fVerbose )
- Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Llb_Mnx_t * Llb_MnxStart( Aig_Man_t * pAig, Gia_ParLlb_t * pPars )
-{
- Llb_Mnx_t * p;
-
- p = ABC_CALLOC( Llb_Mnx_t, 1 );
- p->pAig = pAig;
- p->pPars = pPars;
-
- // compute time to stop
- p->pPars->TimeTarget = p->pPars->TimeLimit ? p->pPars->TimeLimit * CLOCKS_PER_SEC + Abc_Clock(): 0;
-
- if ( pPars->fCluster )
- {
-// Llb_Nonlin4Cluster( p->pAig, &p->dd, &p->vOrder, &p->vRoots, pPars->nBddMax, pPars->fVerbose );
-// Cudd_AutodynEnable( p->dd, CUDD_REORDER_SYMM_SIFT );
- Llb4_Nonlin4Sweep( p->pAig, pPars->nBddMax, pPars->nClusterMax, &p->dd, &p->vOrder, &p->vRoots, pPars->fVerbose );
- // set the stop time parameter
- p->dd->TimeStop = p->pPars->TimeTarget;
- }
- else
- {
-// p->vOrder = Llb_Nonlin4CreateOrderSimple( pAig );
- p->vOrder = Llb_Nonlin4CreateOrder( pAig );
- p->dd = Cudd_Init( Vec_IntCountPositive(p->vOrder) + 1, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
- Cudd_AutodynEnable( p->dd, CUDD_REORDER_SYMM_SIFT );
- Cudd_SetMaxGrowth( p->dd, 1.05 );
- // set the stop time parameter
- p->dd->TimeStop = p->pPars->TimeTarget;
- p->vRoots = Llb_Nonlin4DerivePartitions( p->dd, pAig, p->vOrder );
- }
-
- Llb_Nonlin4SetupVarMap( p->dd, pAig, p->vOrder );
- p->vVars2Q = Llb_Nonlin4CreateVars2Q( p->dd, pAig, p->vOrder, p->pPars->fBackward );
- p->vRings = Vec_PtrAlloc( 100 );
-
- if ( pPars->fReorder )
- Llb_Nonlin4Reorder( p->dd, 0, 1 );
- return p;
-}
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_MnxStop( Llb_Mnx_t * p )
-{
- DdNode * bTemp;
- int i;
- if ( p->pPars->fVerbose )
- {
- p->timeReo = Cudd_ReadReorderingTime(p->dd);
- p->timeOther = p->timeTotal - p->timeImage - p->timeRemap;
- ABC_PRTP( "Image ", p->timeImage, p->timeTotal );
- ABC_PRTP( "Remap ", p->timeRemap, p->timeTotal );
- ABC_PRTP( "Other ", p->timeOther, p->timeTotal );
- ABC_PRTP( "TOTAL ", p->timeTotal, p->timeTotal );
- ABC_PRTP( " reo ", p->timeReo, p->timeTotal );
- }
- // remove BDDs
- if ( p->bBad )
- Cudd_RecursiveDeref( p->dd, p->bBad );
- if ( p->bReached )
- Cudd_RecursiveDeref( p->dd, p->bReached );
- if ( p->bCurrent )
- Cudd_RecursiveDeref( p->dd, p->bCurrent );
- if ( p->bNext )
- Cudd_RecursiveDeref( p->dd, p->bNext );
- if ( p->vRings )
- Vec_PtrForEachEntry( DdNode *, p->vRings, bTemp, i )
- Cudd_RecursiveDeref( p->dd, bTemp );
- if ( p->vRoots )
- Vec_PtrForEachEntry( DdNode *, p->vRoots, bTemp, i )
- Cudd_RecursiveDeref( p->dd, bTemp );
- // remove arrays
- Vec_PtrFreeP( &p->vRings );
- Vec_PtrFreeP( &p->vRoots );
-//Cudd_PrintInfo( p->dd, stdout );
- Extra_StopManager( p->dd );
- Vec_IntFreeP( &p->vOrder );
- Vec_IntFreeP( &p->vVars2Q );
- ABC_FREE( p );
-}
-
-
-/**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Llb_MnxCheckNextStateVars( Llb_Mnx_t * p )
-{
- Aig_Obj_t * pObj;
- int i, Counter0 = 0, Counter1 = 0;
- Saig_ManForEachLi( p->pAig, pObj, i )
- if ( Saig_ObjIsLo(p->pAig, Aig_ObjFanin0(pObj)) )
- {
- if ( Aig_ObjFaninC0(pObj) )
- Counter0++;
- else
- Counter1++;
- }
- printf( "Total = %d. Direct LO = %d. Compl LO = %d.\n", Aig_ManRegNum(p->pAig), Counter1, Counter0 );
-}
-
-/**Function*************************************************************
-
- Synopsis [Finds balanced cut.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Llb_Nonlin4CoreReach( Aig_Man_t * pAig, Gia_ParLlb_t * pPars )
-{
- Llb_Mnx_t * pMnn;
- int RetValue = -1;
- if ( pPars->fVerbose )
- Aig_ManPrintStats( pAig );
- if ( pPars->fCluster && Aig_ManObjNum(pAig) >= (1 << 15) )
- {
- printf( "The number of objects is more than 2^15. Clustering cannot be used.\n" );
- return RetValue;
- }
- {
- abctime clk = Abc_Clock();
- pMnn = Llb_MnxStart( pAig, pPars );
-//Llb_MnxCheckNextStateVars( pMnn );
- if ( !pPars->fSkipReach )
- RetValue = Llb_Nonlin4Reachability( pMnn );
- pMnn->timeTotal = Abc_Clock() - clk;
- Llb_MnxStop( pMnn );
- }
- return RetValue;
-}
-
-
-/**Function*************************************************************
-
- Synopsis [Takes an AIG and returns an AIG representing reachable states.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-Aig_Man_t * Llb_ReachableStates( Aig_Man_t * pAig )
-{
- extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters );
- Vec_Int_t * vPermute;
- Vec_Ptr_t * vNames;
- Gia_ParLlb_t Pars, * pPars = &Pars;
- DdManager * dd;
- DdNode * bReached;
- Llb_Mnx_t * pMnn;
- Abc_Ntk_t * pNtk, * pNtkMuxes;
- Aig_Obj_t * pObj;
- int i, RetValue;
- abctime clk = Abc_Clock();
-
- // create parameters
- Llb_ManSetDefaultParams( pPars );
- pPars->fSkipOutCheck = 1;
- pPars->fCluster = 0;
- pPars->fReorder = 0;
- pPars->fSilent = 1;
- pPars->nBddMax = 100;
- pPars->nClusterMax = 500;
-
- // run reachability
- pMnn = Llb_MnxStart( pAig, pPars );
- RetValue = Llb_Nonlin4Reachability( pMnn );
- assert( RetValue == 1 );
-
- // print BDD
-// Extra_bddPrint( pMnn->dd, pMnn->bReached );
-// Extra_bddPrintSupport( pMnn->dd, pMnn->bReached );
-// printf( "\n" );
-
- // collect flop output variables
- vPermute = Vec_IntStartFull( Cudd_ReadSize(pMnn->dd) );
- Saig_ManForEachLo( pAig, pObj, i )
- Vec_IntWriteEntry( vPermute, Llb_ObjBddVar(pMnn->vOrder, pObj), i );
-
- // transfer the reached state BDD into the new manager
- dd = Cudd_Init( Saig_ManRegNum(pAig), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
- Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
- bReached = Extra_TransferPermute( pMnn->dd, dd, pMnn->bReached, Vec_IntArray(vPermute) ); Cudd_Ref( bReached );
- Vec_IntFree( vPermute );
- assert( Cudd_ReadSize(dd) == Saig_ManRegNum(pAig) );
-
- // quit reachability engine
- pMnn->timeTotal = Abc_Clock() - clk;
- Llb_MnxStop( pMnn );
-
- // derive the network
- vNames = Abc_NodeGetFakeNames( Saig_ManRegNum(pAig) );
- pNtk = Abc_NtkDeriveFromBdd( dd, bReached, "reached", vNames );
- Abc_NodeFreeNames( vNames );
- Cudd_RecursiveDeref( dd, bReached );
- Cudd_Quit( dd );
-
- // convert
- pNtkMuxes = Abc_NtkBddToMuxes( pNtk );
- Abc_NtkDelete( pNtk );
- pNtk = Abc_NtkStrash( pNtkMuxes, 0, 1, 0 );
- Abc_NtkDelete( pNtkMuxes );
- pAig = Abc_NtkToDar( pNtk, 0, 0 );
- Abc_NtkDelete( pNtk );
- return pAig;
-}
-Gia_Man_t * Llb_ReachableStatesGia( Gia_Man_t * p )
-{
- Gia_Man_t * pNew;
- Aig_Man_t * pAig, * pReached;
- pAig = Gia_ManToAigSimple( p );
- pReached = Llb_ReachableStates( pAig );
- Aig_ManStop( pAig );
- pNew = Gia_ManFromAigSimple( pReached );
- Aig_ManStop( pReached );
- return pNew;
-}
-
-////////////////////////////////////////////////////////////////////////
-/// END OF FILE ///
-////////////////////////////////////////////////////////////////////////
-
-
-ABC_NAMESPACE_IMPL_END
-