Commit fb918249 by Alan Mishchenko

Variable timeframe abstraction.

parent 20d05d39
...@@ -38,7 +38,7 @@ struct Vta_Obj_t_ ...@@ -38,7 +38,7 @@ struct Vta_Obj_t_
unsigned Prio : 28; // related to VTA_LARGE unsigned Prio : 28; // related to VTA_LARGE
unsigned Value : 2; unsigned Value : 2;
unsigned fAdded : 1; unsigned fAdded : 1;
unsigned fNew : 1; unsigned fVisit : 1;
}; };
typedef struct Vta_Man_t_ Vta_Man_t; // manager typedef struct Vta_Man_t_ Vta_Man_t; // manager
...@@ -68,6 +68,9 @@ struct Vta_Man_t_ ...@@ -68,6 +68,9 @@ struct Vta_Man_t_
sat_solver2 * pSat; // incremental SAT solver sat_solver2 * pSat; // incremental SAT solver
}; };
// ternary simulation
#define VTA_VAR0 1 #define VTA_VAR0 1
#define VTA_VAR1 2 #define VTA_VAR1 2
#define VTA_VARX 3 #define VTA_VARX 3
...@@ -84,16 +87,23 @@ static inline int Vta_ValIs1( Vta_Obj_t * pThis, int fCompl ) ...@@ -84,16 +87,23 @@ static inline int Vta_ValIs1( Vta_Obj_t * pThis, int fCompl )
static inline Vta_Obj_t * Vta_ManObj( Vta_Man_t * p, int i ) { assert( i >= 0 && i < p->nObjs ); return i ? p->pObjs + i : NULL; } static inline Vta_Obj_t * Vta_ManObj( Vta_Man_t * p, int i ) { assert( i >= 0 && i < p->nObjs ); return i ? p->pObjs + i : NULL; }
static inline int Vta_ObjId( Vta_Man_t * p, Vta_Obj_t * pObj ) { assert( pObj > p->pObjs && pObj < p->pObjs + p->nObjs ); return pObj - p->pObjs; } static inline int Vta_ObjId( Vta_Man_t * p, Vta_Obj_t * pObj ) { assert( pObj > p->pObjs && pObj < p->pObjs + p->nObjs ); return pObj - p->pObjs; }
//static inline unsigned * Vta_ObjAbsOld( Vta_Man_t * p, int i ) { assert( i >= 0 && i < p->nObjs ); return (unsigned *)Vec_IntEntryP( p->vAbs, i*p->nWords ); }
//static inline unsigned * Vta_ObjAbsNew( Vta_Man_t * p, int i ) { assert( i >= 0 && i < p->nObjs ); return (unsigned *)Vec_IntEntryP( p->vAbsNew, i*p->nWords ); }
#define Vta_ManForEachObj( p, pObj, i ) \ #define Vta_ManForEachObj( p, pObj, i ) \
for ( i = 1; (i < p->nObjs) && ((pObj) = Vta_ManObj(p, i)); i++ ) for ( i = 1; (i < p->nObjs) && ((pObj) = Vta_ManObj(p, i)); i++ )
#define Vta_ManForEachObjVec( vVec, p, pObj, i ) \ #define Vta_ManForEachObjVec( vVec, p, pObj, i ) \
for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))); i++ ) for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))); i++ )
#define Vta_ManForEachObjVecReverse( vVec, p, pObj, i ) \ #define Vta_ManForEachObjVecReverse( vVec, p, pObj, i ) \
for ( i = Vec_IntSize(vVec) - 1; (i >= 1) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))); i-- ) for ( i = Vec_IntSize(vVec) - 1; (i >= 1) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))); i-- )
#define Vta_ManForEachObjObjVec( vVec, p, pObj, pObjG, i ) \
for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))) && ((pObjG) = Gia_ManObj(p->pGia, pObj->iObj)); i++ )
#define Vta_ManForEachObjObjVecReverse( vVec, p, pObj, pObjG, i ) \
for ( i = Vec_IntSize(vVec) - 1; (i >= 1) && ((pObj) = Vta_ManObj(p, Vec_IntEntry(vVec,i))) && ((pObjG) = Gia_ManObj(p->pGia, pObj->iObj)); i-- )
#define Vta_ManForEachObjObj( p, pObjVta, pObjGia, i ) \
for ( i = 1; (i < p->nObjs) && ((pObjVta) = Vta_ManObj(p, i)) && ((pObjGia) = Gia_ManObj(p->pGia, pObjVta->iObj)); i++ )
#define Vta_ManForEachObjObjReverse( p, pObjVta, pObjGia, i ) \
for ( i = Vec_IntSize(vVec) - 1; (i >= 1) && ((pObjVta) = Vta_ManObj(p, i)) && ((pObjGia) = Gia_ManObj(p->pGia, pObjVta->iObj)); i++ )
// abstraction is given as an array of integers: // abstraction is given as an array of integers:
// - the first entry is the number of timeframes (F) // - the first entry is the number of timeframes (F)
// - the next (F+1) entries give the beginning position of each timeframe // - the next (F+1) entries give the beginning position of each timeframe
...@@ -365,7 +375,6 @@ static inline Vta_Obj_t * Vga_ManFindOrAdd( Vta_Man_t * p, int iObj, int iFrame ...@@ -365,7 +375,6 @@ static inline Vta_Obj_t * Vga_ManFindOrAdd( Vta_Man_t * p, int iObj, int iFrame
pThis = Vta_ManObj(p, *pPlace); pThis = Vta_ManObj(p, *pPlace);
pThis->iObj = iObj; pThis->iObj = iObj;
pThis->iFrame = iFrame; pThis->iFrame = iFrame;
pThis->fNew = 1;
return pThis; return pThis;
} }
static inline void Vga_ManDelete( Vta_Man_t * p, int iObj, int iFrame ) static inline void Vga_ManDelete( Vta_Man_t * p, int iObj, int iFrame )
...@@ -377,6 +386,33 @@ static inline void Vga_ManDelete( Vta_Man_t * p, int iObj, int iFrame ) ...@@ -377,6 +386,33 @@ static inline void Vga_ManDelete( Vta_Man_t * p, int iObj, int iFrame )
pThis->iNext = -1; pThis->iNext = -1;
} }
/**Function*************************************************************
Synopsis [Derives counter-example using current assignments.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Cex_t * Vga_ManDeriveCex( Vta_Man_t * p )
{
Abc_Cex_t * pCex;
Vta_Obj_t * pThis;
Gia_Obj_t * pObj;
int i;
pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 );
pCex->iPo = 0;
pCex->iFrame = p->pPars->iFrame;
Vta_ManForEachObjObj( p, pThis, pObj, i )
if ( Gia_ObjIsPi(p->pGia, pObj) && sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) )
Abc_InfoSetBit( pCex->pData, pCex->nRegs + pThis->iFrame * pCex->nPis + Gia_ObjCioId(pObj) );
return pCex;
}
/**Function************************************************************* /**Function*************************************************************
Synopsis [Remaps core into frame/node pairs.] Synopsis [Remaps core into frame/node pairs.]
...@@ -451,6 +487,77 @@ int Vta_ManObjIsUsed( Vta_Man_t * p, int iObj ) ...@@ -451,6 +487,77 @@ int Vta_ManObjIsUsed( Vta_Man_t * p, int iObj )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Finds predecessors of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vta_ObjPreds( Vta_Man_t * p, Vta_Obj_t * pThis, Gia_Obj_t * pObj, Vta_Obj_t ** ppThis0, Vta_Obj_t ** ppThis1 )
{
*ppThis0 = NULL;
*ppThis1 = NULL;
if ( !pThis->fAdded )
return;
assert( !Gia_ObjIsPi(p->pGia, pObj) );
if ( Gia_ObjIsConst0(pObj) || (Gia_ObjIsCi(pObj) && pThis->iFrame == 0) )
return;
if ( Gia_ObjIsAnd(pObj) )
{
*ppThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame );
*ppThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame );
assert( *ppThis0 && *ppThis1 );
return;
}
assert( Gia_ObjIsRo(p->pGia, pObj) && pThis->iFrame > 0 );
pObj = Gia_ObjRoToRi( p->pGia, pObj );
*ppThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 );
assert( *ppThis0 );
}
/**Function*************************************************************
Synopsis [Collect const/PI/RO/AND in a topological order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Vta_ManCollectNodes_rec( Vta_Man_t * p, Vta_Obj_t * pThis, Vec_Int_t * vOrder )
{
Gia_Obj_t * pObj;
Vta_Obj_t * pThis0, * pThis1;
if ( !pThis->fVisit )
return;
pThis->fVisit = 1;
pObj = Gia_ManObj( p->pGia, pThis->iObj );
Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 );
if ( pThis0 ) Vta_ManCollectNodes_rec( p, pThis0, vOrder );
if ( pThis1 ) Vta_ManCollectNodes_rec( p, pThis1, vOrder );
Vec_IntPush( vOrder, Vta_ObjId(p, pThis) );
}
Vec_Int_t * Vta_ManCollectNodes( Vta_Man_t * p, int f )
{
Vta_Obj_t * pThis;
Gia_Obj_t * pObj;
Vec_IntClear( p->vOrder );
pObj = Gia_ManPo( p->pGia, 0 );
pThis = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), f );
assert( pThis != NULL );
assert( !pThis->fVisit );
Vta_ManCollectNodes_rec( p, pThis, p->vOrder );
assert( pThis->fVisit );
return p->vOrder;
}
/**Function*************************************************************
Synopsis [Refines abstraction.] Synopsis [Refines abstraction.]
Description [] Description []
...@@ -460,45 +567,45 @@ int Vta_ManObjIsUsed( Vta_Man_t * p, int iObj ) ...@@ -460,45 +567,45 @@ int Vta_ManObjIsUsed( Vta_Man_t * p, int iObj )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p ) Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p, int f )
{ {
Abc_Cex_t * pCex = NULL; Abc_Cex_t * pCex = NULL;
Vec_Int_t * vOrder, * vTermsToAdd;
Vec_Ptr_t * vTermsUsed, * vTermsUnused; Vec_Ptr_t * vTermsUsed, * vTermsUnused;
Vta_Obj_t * pThis, * pThis0, * pThis1, * pTop; Vta_Obj_t * pThis, * pThis0, * pThis1, * pTop;
Gia_Obj_t * pObj; Gia_Obj_t * pObj;
int i, Counter; int i, Counter;
assert( Vec_IntSize(p->vOrder) == p->nObjs - 1 );
// clean depth field // collect nodes in a topological order
Vta_ManForEachObj( p, pThis, i ) vOrder = Vta_ManCollectNodes( p, f );
Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i )
{ {
pThis->Prio = VTA_LARGE; pThis->Prio = VTA_LARGE;
pThis->Value = sat_solver2_var_value(p->pSat, i) ? VTA_VAR1 : VTA_VAR0; pThis->Value = sat_solver2_var_value(p->pSat, i) ? VTA_VAR1 : VTA_VAR0;
pThis->fVisit = 0;
} }
// set the last node // compute distance in reverse order
pThis = Vta_ManObj( p, Vec_IntEntryLast(p->vOrder) ); pThis = Vta_ManObj( p, p->nObjs - 1 );
pThis->Prio = 1; pThis->Prio = 1;
// collect used and unused terms
// consider nodes in the reverse order
vTermsUsed = Vec_PtrAlloc( 1015 ); vTermsUsed = Vec_PtrAlloc( 1015 );
vTermsUnused = Vec_PtrAlloc( 1016 ); vTermsUnused = Vec_PtrAlloc( 1016 );
Vta_ManForEachObjVecReverse( p->vOrder, p, pThis, i ) Vta_ManForEachObjObjVecReverse( vOrder, p, pThis, pObj, i )
{ {
// skip unreachable ones // there is no unreachable states
if ( pThis->Prio == VTA_LARGE ) assert( pThis->Prio < VTA_LARGE );
continue; // skip constants and PIs
// skip contants and PIs
pObj = Gia_ManObj( p->pGia, pThis->iObj );
if ( Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) ) if ( Gia_ObjIsConst0(pObj) || Gia_ObjIsPi(p->pGia, pObj) )
{ {
pThis->Prio = 0; pThis->Prio = 0; // set highest priority
continue; continue;
} }
// collect useful terminals // collect useful terminals
assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) ); assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) );
if ( !pThis->fAdded ) if ( !pThis->fAdded )
{ {
assert( pThis->Prio > 0 || pThis->Prio < VTA_LARGE ); assert( pThis->Prio > 0 );
if ( Vta_ManObjIsUsed(p, pThis->iObj) ) if ( Vta_ManObjIsUsed(p, pThis->iObj) )
Vec_PtrPush( vTermsUsed, pThis ); Vec_PtrPush( vTermsUsed, pThis );
else else
...@@ -506,57 +613,45 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p ) ...@@ -506,57 +613,45 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p )
continue; continue;
} }
// propagate // propagate
if ( Gia_ObjIsAnd(pObj) ) Vta_ObjPreds( p, pThis, pObj, &pThis0, &pThis1 );
{ if ( pThis0 )
pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame );
pThis1 = Vga_ManFind( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame );
assert( pThis0 && pThis1 );
pThis0->Prio = Abc_MinInt( pThis0->Prio, pThis->Prio + 1 ); pThis0->Prio = Abc_MinInt( pThis0->Prio, pThis->Prio + 1 );
if ( pThis1 )
pThis1->Prio = Abc_MinInt( pThis1->Prio, pThis->Prio + 1 ); pThis1->Prio = Abc_MinInt( pThis1->Prio, pThis->Prio + 1 );
}
else if ( Gia_ObjIsRo(p->pGia, pObj) )
{
if ( pThis->iFrame == 0 )
pThis->Prio = 0;
else
{
pObj = Gia_ObjRoToRi( p->pGia, pObj );
pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 );
assert( pThis0 );
pThis0->Prio = Abc_MinInt( pThis0->Prio, pThis->Prio + 1 );
}
}
else assert( 0 );
} }
// objects with equal distance should receive priority based on number // objects with equal distance should receive priority based on number
// those objects whose prototypes have been added in other timeframes // those objects whose prototypes have been added in other timeframes
// should have higher priority than the current object // should have higher priority than the current object
Vec_PtrSort( vTermsUsed, (int (*)(void))Vta_ManComputeDepthIncrease ); Vec_PtrSort( vTermsUsed, (int (*)(void))Vta_ManComputeDepthIncrease );
Vec_PtrSort( vTermsUnused, (int (*)(void))Vta_ManComputeDepthIncrease ); Vec_PtrSort( vTermsUnused, (int (*)(void))Vta_ManComputeDepthIncrease );
if ( Vec_PtrSize(vTermsUsed) > 1 )
{
pThis0 = (Vta_Obj_t *)Vec_PtrEntry(vTermsUsed, 0);
pThis1 = (Vta_Obj_t *)Vec_PtrEntryLast(vTermsUsed);
assert( pThis0->Prio <= pThis1->Prio );
}
// assign the priority based on these orders // assign the priority based on these orders
Counter = 1; Counter = 1;
Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i ) Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i )
pThis->Prio = Counter++; pThis->Prio = Counter++;
Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUnused, pThis, i ) Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUnused, pThis, i )
pThis->Prio = Counter++; pThis->Prio = Counter++;
Vec_PtrFree( vTermsUsed );
Vec_PtrFree( vTermsUnused );
// propagate in the direct order // propagate in the direct order
Vta_ManForEachObjVec( p->vOrder, p, pThis, i ) Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i )
{ {
assert( pThis->fNew == 0 ); assert( pThis->fVisit == 0 );
// skip unreachable ones assert( pThis->Prio < VTA_LARGE );
if ( pThis->Prio == VTA_LARGE )
continue;
// skip terminal objects // skip terminal objects
if ( !pThis->fAdded ) if ( !pThis->fAdded )
continue; continue;
// assumes that values are assigned!!! // assumes that values are assigned!!!
assert( pThis->Value != 0 ); assert( pThis->Value != 0 );
// propagate // propagate
pObj = Gia_ManObj( p->pGia, pThis->iObj );
assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) ); assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) );
if ( Gia_ObjIsAnd(pObj) ) if ( Gia_ObjIsAnd(pObj) )
{ {
pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame ); pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame );
...@@ -570,7 +665,7 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p ) ...@@ -570,7 +665,7 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p )
else if ( pThis->Value == VTA_VAR0 ) else if ( pThis->Value == VTA_VAR0 )
{ {
if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) )
pThis->Prio = Abc_MinInt( pThis0->Prio, pThis1->Prio ); pThis->Prio = Abc_MinInt( pThis0->Prio, pThis1->Prio ); // choice!!!
else if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) ) else if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) )
pThis->Prio = pThis0->Prio; pThis->Prio = pThis0->Prio;
else if ( Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) else if ( Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) )
...@@ -591,27 +686,25 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p ) ...@@ -591,27 +686,25 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p )
} }
} }
Vec_PtrClear( vTermsUsed );
// select important values // select important values
pTop = Vta_ManObj( p, Vec_IntEntryLast(p->vOrder) ); pTop = Vta_ManObj( p, Vec_IntEntryLast(p->vOrder) );
pTop->fNew = 1; pTop->fVisit = 1;
Vta_ManForEachObjVec( p->vOrder, p, pThis, i ) vTermsToAdd = Vec_IntAlloc( 100 );
Vta_ManForEachObjObjVecReverse( vOrder, p, pThis, pObj, i )
{ {
if ( pThis->fNew == 0 ) if ( !pThis->fVisit )
continue; continue;
pThis->fNew = 0; pThis->fVisit = 0;
assert( pThis->Prio >= 0 && pThis->Prio <= pTop->Prio ); assert( pThis->Prio >= 0 && pThis->Prio <= pTop->Prio );
// skip terminal objects // skip terminal objects
if ( !pThis->fAdded ) if ( !pThis->fAdded )
{ {
Vec_PtrPush( vTermsUsed, pThis ); Vec_IntPush( vTermsToAdd, Vta_ObjId(p, pThis) );
continue; continue;
} }
// assumes that values are assigned!!! // assumes that values are assigned!!!
assert( pThis->Value != 0 ); assert( pThis->Value != 0 );
// propagate // propagate
pObj = Gia_ManObj( p->pGia, pThis->iObj );
assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) ); assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) );
if ( Gia_ObjIsAnd(pObj) ) if ( Gia_ObjIsAnd(pObj) )
{ {
...@@ -621,24 +714,36 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p ) ...@@ -621,24 +714,36 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p )
if ( pThis->Value == VTA_VAR1 ) if ( pThis->Value == VTA_VAR1 )
{ {
assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) ); assert( Vta_ValIs1(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs1(pThis1, Gia_ObjFaninC1(pObj)) );
pThis0->fNew = 1; assert( pThis0->Prio <= pThis->Prio );
pThis1->fNew = 1; assert( pThis1->Prio <= pThis->Prio );
pThis0->fVisit = 1;
pThis1->fVisit = 1;
} }
else if ( pThis->Value == VTA_VAR0 ) else if ( pThis->Value == VTA_VAR0 )
{ {
if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) && Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) )
{ {
assert( pThis0->Prio <= pThis->Prio ); if ( pThis0->Prio <= pThis1->Prio ) // choice!!!
assert( pThis1->Prio <= pThis->Prio ); {
if ( pThis0->Prio <= pThis1->Prio ) pThis0->fVisit = 1;
pThis0->fNew = 1; assert( pThis0->Prio == pThis->Prio );
}
else else
pThis1->fNew = 1; {
pThis1->fVisit = 1;
assert( pThis1->Prio == pThis->Prio );
}
} }
else if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) ) else if ( Vta_ValIs0(pThis0, Gia_ObjFaninC0(pObj)) )
pThis0->fNew = 1; {
pThis0->fVisit = 1;
assert( pThis0->Prio == pThis->Prio );
}
else if ( Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) ) else if ( Vta_ValIs0(pThis1, Gia_ObjFaninC1(pObj)) )
pThis1->fNew = 1; {
pThis1->fVisit = 1;
assert( pThis1->Prio == pThis->Prio );
}
else assert( 0 ); else assert( 0 );
} }
else assert( 0 ); else assert( 0 );
...@@ -650,21 +755,22 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p ) ...@@ -650,21 +755,22 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p )
pObj = Gia_ObjRoToRi( p->pGia, pObj ); pObj = Gia_ObjRoToRi( p->pGia, pObj );
pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 ); pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 );
assert( pThis0 ); assert( pThis0 );
pThis0->fNew = 1; pThis0->fVisit = 1;
assert( pThis0->Prio == pThis->Prio );
} }
} }
else assert( 0 );
} }
// verify // verify
Vta_ManForEachObj( p, pThis, i ) Vta_ManForEachObjVec( p->vOrder, p, pThis, i )
pThis->Value = VTA_VARX; pThis->Value = VTA_VARX;
Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i ) Vta_ManForEachObjVec( vTermsToAdd, p, pThis, i )
pThis->Value = sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ? VTA_VAR1 : VTA_VAR0; pThis->Value = sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ? VTA_VAR1 : VTA_VAR0;
// simulate // simulate
Vta_ManForEachObjVec( p->vOrder, p, pThis, i ) Vta_ManForEachObjObjVec( vOrder, p, pThis, pObj, i )
{ {
assert( pThis->fNew == 0 ); assert( pThis->fVisit == 0 );
pObj = Gia_ManObj( p->pGia, pThis->iObj );
if ( Gia_ObjIsAnd(pObj) ) if ( Gia_ObjIsAnd(pObj) )
{ {
pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame ); pThis0 = Vga_ManFind( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame );
...@@ -691,10 +797,11 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p ) ...@@ -691,10 +797,11 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p )
else else
pThis->Value = VTA_VARX; pThis->Value = VTA_VARX;
} }
else
pThis->Value = VTA_VAR0;
} }
// double check the solver // double check the solver
if ( pThis->Value != VTA_VARX ) assert( pThis->Value == VTA_VARX || (int)pThis->Value == (sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ? VTA_VAR1 : VTA_VAR0) );
assert( (int)pThis->Value == (sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) ? VTA_VAR1 : VTA_VAR0) );
} }
// check the output // check the output
...@@ -703,15 +810,15 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p ) ...@@ -703,15 +810,15 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p )
// produce true counter-example // produce true counter-example
if ( pTop->Prio == 0 ) if ( pTop->Prio == 0 )
pCex = Vga_ManDeriveCex( p );
/*
{ {
pCex = NULL;
pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 ); pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 );
pCex->iPo = 0; pCex->iPo = 0;
pCex->iFrame = p->pPars->iFrame; pCex->iFrame = p->pPars->iFrame;
Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i ) Vta_ManForEachObjObjVec( vTermsToAdd, p, pThis, pObj, i )
{ {
assert( pThis->Value == VTA_VAR0 || pThis->Value == VTA_VAR1 ); assert( pThis->Value == VTA_VAR0 || pThis->Value == VTA_VAR1 );
pObj = Gia_ManObj( p->pGia, pThis->iObj );
assert( Gia_ObjIsConst0(pObj) || Gia_ObjIsCi(pObj) ); assert( Gia_ObjIsConst0(pObj) || Gia_ObjIsCi(pObj) );
if ( Gia_ObjIsRo(p->pGia, pObj) ) if ( Gia_ObjIsRo(p->pGia, pObj) )
assert( pThis->iFrame == 0 && pThis->Value == VTA_VAR0 ); assert( pThis->iFrame == 0 && pThis->Value == VTA_VAR0 );
...@@ -719,35 +826,14 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p ) ...@@ -719,35 +826,14 @@ Abc_Cex_t * Vta_ManRefineAbstraction( Vta_Man_t * p )
Abc_InfoSetBit( pCex->pData, pCex->nRegs + pThis->iFrame * pCex->nPis + Gia_ObjCioId(pObj) ); Abc_InfoSetBit( pCex->pData, pCex->nRegs + pThis->iFrame * pCex->nPis + Gia_ObjCioId(pObj) );
} }
} }
*/
// perform refinement // perform refinement
else else
{ {
Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i ) Vta_ManForEachObjVec( vTermsToAdd, p, pThis, i )
{
assert( !pThis->fAdded );
pObj = Gia_ManObj( p->pGia, pThis->iObj );
if ( Gia_ObjIsAnd(pObj) )
{
Vga_ManFindOrAdd( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame );
Vga_ManFindOrAdd( p, Gia_ObjFaninId1p(p->pGia, pObj), pThis->iFrame );
}
else if ( Gia_ObjIsRo(p->pGia, pObj) )
{
if ( pThis->iFrame > 0 )
{
pObj = Gia_ObjRoToRi( p->pGia, pObj );
Vga_ManFindOrAdd( p, Gia_ObjFaninId0p(p->pGia, pObj), pThis->iFrame-1 );
}
}
else assert( 0 );
}
// add clauses
Vec_PtrForEachEntry( Vta_Obj_t *, vTermsUsed, pThis, i )
Vga_ManAddClausesOne( p, pThis->iObj, pThis->iFrame ); Vga_ManAddClausesOne( p, pThis->iObj, pThis->iFrame );
} }
Vec_IntFree( vTermsToAdd );
Vec_PtrFree( vTermsUsed );
Vec_PtrFree( vTermsUnused );
return pCex; return pCex;
} }
...@@ -848,7 +934,7 @@ void Vga_ManStop( Vta_Man_t * p ) ...@@ -848,7 +934,7 @@ void Vga_ManStop( Vta_Man_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Vec_Int_t * Vta_ManUnsatCore( int iLit, Vec_Int_t * vCla2Var, sat_solver2 * pSat, int nConfMax, int fVerbose, int * piRetValue ) Vec_Int_t * Vta_ManUnsatCore( int iLit, Vec_Int_t * vCla2Var, sat_solver2 * pSat, int nConfMax, int fVerbose, int * piRetValue, int * pnConfls )
{ {
Vec_Int_t * vPres; Vec_Int_t * vPres;
Vec_Int_t * vCore; Vec_Int_t * vCore;
...@@ -856,6 +942,8 @@ Vec_Int_t * Vta_ManUnsatCore( int iLit, Vec_Int_t * vCla2Var, sat_solver2 * pSat ...@@ -856,6 +942,8 @@ Vec_Int_t * Vta_ManUnsatCore( int iLit, Vec_Int_t * vCla2Var, sat_solver2 * pSat
int nConfPrev = pSat->stats.conflicts; int nConfPrev = pSat->stats.conflicts;
if ( piRetValue ) if ( piRetValue )
*piRetValue = 1; *piRetValue = 1;
if ( pnConfls )
*pnConfls = 0;
// solve the problem // solve the problem
RetValue = sat_solver2_solve( pSat, &iLit, &iLit+1, (ABC_INT64_T)nConfMax, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); RetValue = sat_solver2_solve( pSat, &iLit, &iLit+1, (ABC_INT64_T)nConfMax, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
if ( RetValue == l_Undef ) if ( RetValue == l_Undef )
...@@ -870,9 +958,11 @@ Vec_Int_t * Vta_ManUnsatCore( int iLit, Vec_Int_t * vCla2Var, sat_solver2 * pSat ...@@ -870,9 +958,11 @@ Vec_Int_t * Vta_ManUnsatCore( int iLit, Vec_Int_t * vCla2Var, sat_solver2 * pSat
*piRetValue = 0; *piRetValue = 0;
return NULL; return NULL;
} }
if ( pnConfls )
*pnConfls = (int)pSat->stats.conflicts - nConfPrev;
if ( fVerbose ) if ( fVerbose )
{ {
printf( "%6d", (int)pSat->stats.conflicts - nConfPrev ); // printf( "%6d", (int)pSat->stats.conflicts - nConfPrev );
// printf( "UNSAT after %7d conflicts. ", pSat->stats.conflicts ); // printf( "UNSAT after %7d conflicts. ", pSat->stats.conflicts );
// Abc_PrintTime( 1, "Time", clock() - clk ); // Abc_PrintTime( 1, "Time", clock() - clk );
} }
...@@ -920,7 +1010,7 @@ Vec_Int_t * Vta_ManUnsatCore( int iLit, Vec_Int_t * vCla2Var, sat_solver2 * pSat ...@@ -920,7 +1010,7 @@ Vec_Int_t * Vta_ManUnsatCore( int iLit, Vec_Int_t * vCla2Var, sat_solver2 * pSat
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Vta_ManAbsPrintFrame( Vta_Man_t * p, Vec_Int_t * vCore, int nFrames ) void Vta_ManAbsPrintFrame( Vta_Man_t * p, Vec_Int_t * vCore, int nFrames, int fVerbose )
{ {
unsigned * pInfo; unsigned * pInfo;
int * pCountAll, * pCountUni; int * pCountAll, * pCountUni;
...@@ -934,7 +1024,7 @@ void Vta_ManAbsPrintFrame( Vta_Man_t * p, Vec_Int_t * vCore, int nFrames ) ...@@ -934,7 +1024,7 @@ void Vta_ManAbsPrintFrame( Vta_Man_t * p, Vec_Int_t * vCore, int nFrames )
iFrame = (Entry >> p->nObjBits); iFrame = (Entry >> p->nObjBits);
assert( iFrame < nFrames ); assert( iFrame < nFrames );
pInfo = (unsigned *)Vec_IntEntryP( p->vSeens, p->nWords * iObj ); pInfo = (unsigned *)Vec_IntEntryP( p->vSeens, p->nWords * iObj );
if ( Abc_InfoHasBit(pInfo, iFrame) == 0 ) if ( !Abc_InfoHasBit(pInfo, iFrame) )
{ {
Abc_InfoSetBit( pInfo, iFrame ); Abc_InfoSetBit( pInfo, iFrame );
pCountUni[iFrame+1]++; pCountUni[iFrame+1]++;
...@@ -948,14 +1038,17 @@ void Vta_ManAbsPrintFrame( Vta_Man_t * p, Vec_Int_t * vCore, int nFrames ) ...@@ -948,14 +1038,17 @@ void Vta_ManAbsPrintFrame( Vta_Man_t * p, Vec_Int_t * vCore, int nFrames )
p->nSeenGla++; p->nSeenGla++;
} }
} }
// printf( "%5d%5d", pCountAll[0], pCountUni[0] ); if ( fVerbose )
printf( "%6d", p->nSeenGla ); {
printf( "%6d", pCountAll[0] ); // printf( "%5d%5d", pCountAll[0], pCountUni[0] );
for ( k = 0; k < nFrames; k++ ) printf( "%6d", p->nSeenGla );
// printf( "%5d%5d ", pCountAll[k+1], pCountUni[k+1] ); printf( "%6d", pCountAll[0] );
printf( "%4d", pCountAll[k+1] ); for ( k = 0; k < nFrames; k++ )
printf( "\n" ); // printf( "%5d%5d ", pCountAll[k+1], pCountUni[k+1] );
fflush( stdout ); printf( "%4d", pCountAll[k+1] );
printf( "\n" );
fflush( stdout );
}
ABC_FREE( pCountAll ); ABC_FREE( pCountAll );
ABC_FREE( pCountUni ); ABC_FREE( pCountUni );
} }
...@@ -1066,6 +1159,7 @@ static inline int Vga_ManGetOutLit( Vta_Man_t * p, int f ) ...@@ -1066,6 +1159,7 @@ static inline int Vga_ManGetOutLit( Vta_Man_t * p, int f )
return Abc_Var2Lit( Vta_ObjId(p, pThis), Gia_ObjFaninC0(pObj) ); return Abc_Var2Lit( Vta_ObjId(p, pThis), Gia_ObjFaninC0(pObj) );
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Collect nodes/flops involved in different timeframes.] Synopsis [Collect nodes/flops involved in different timeframes.]
...@@ -1080,11 +1174,9 @@ static inline int Vga_ManGetOutLit( Vta_Man_t * p, int f ) ...@@ -1080,11 +1174,9 @@ static inline int Vga_ManGetOutLit( Vta_Man_t * p, int f )
int Gia_VtaPerform( Gia_Man_t * pAig, Gia_ParVta_t * pPars ) int Gia_VtaPerform( Gia_Man_t * pAig, Gia_ParVta_t * pPars )
{ {
Vta_Man_t * p; Vta_Man_t * p;
Vta_Obj_t * pThis;
Vec_Int_t * vCore; Vec_Int_t * vCore;
Abc_Cex_t * pCex = NULL; Abc_Cex_t * pCex = NULL;
Gia_Obj_t * pObj; int i, f, nConfls, Status, RetValue = -1;
int i, f, Status, RetValue = -1;
int clk = clock(); int clk = clock();
// preconditions // preconditions
assert( Gia_ManPoNum(pAig) == 1 ); assert( Gia_ManPoNum(pAig) == 1 );
...@@ -1104,78 +1196,61 @@ int Gia_VtaPerform( Gia_Man_t * pAig, Gia_ParVta_t * pPars ) ...@@ -1104,78 +1196,61 @@ int Gia_VtaPerform( Gia_Man_t * pAig, Gia_ParVta_t * pPars )
p->nWords = Vec_IntDoubleWidth( p->vSeens, p->nWords ); p->nWords = Vec_IntDoubleWidth( p->vSeens, p->nWords );
// check this timeframe // check this timeframe
if ( f < p->pPars->nFramesStart ) if ( f < p->pPars->nFramesStart )
{
// load this timeframe
Vga_ManLoadSlice( p, (Vec_Int_t *)Vec_PtrEntry(p->vFrames, f), 0 ); Vga_ManLoadSlice( p, (Vec_Int_t *)Vec_PtrEntry(p->vFrames, f), 0 );
// run SAT solver
vCore = Vta_ManUnsatCore( Vga_ManGetOutLit(p, f), p->vCla2Var, p->pSat, pPars->nConfLimit, p->pPars->fVerbose, &Status );
assert( (vCore != NULL) == (Status == 1) );
if ( Status == -1 )
break;
if ( Status == 0 )
{
// make sure, there was no initial abstraction (otherwise, it was invalid)
assert( pAig->vObjClasses == NULL );
// derive counter-example
pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 );
pCex->iPo = 0;
pCex->iFrame = p->pPars->iFrame;
Vta_ManForEachObj( p, pThis, i )
{
pObj = Gia_ManObj( p->pGia, pThis->iObj );
if ( Gia_ObjIsPi(p->pGia, pObj) && sat_solver2_var_value(p->pSat, Vta_ObjId(p, pThis)) )
Abc_InfoSetBit( pCex->pData, pCex->nRegs + pThis->iFrame * pCex->nPis + Gia_ObjCioId(pObj) );
}
}
}
else else
{ {
/* // create bookmark to be used for rollback
sat_solver2_bookmark( p->pSat );
// load the time frame // load the time frame
int Limit = Abc_MinInt(5, p->pPars->nFramesStart); for ( i = 1; i <= Abc_MinInt(4, p->pPars->nFramesStart); i++ )
for ( i = 1; i <= Limit; i++ )
Vga_ManLoadSlice( p, (Vec_Int_t *)Vec_PtrEntry(p->vCores, f-i), i ); Vga_ManLoadSlice( p, (Vec_Int_t *)Vec_PtrEntry(p->vCores, f-i), i );
// iterate as long as there are counter-examples // iterate as long as there are counter-examples
do { while ( 1 )
vCore = Vta_ManUnsatCore( Vga_ManGetOutLit(p, f), p->vCla2Var, p->pSat, pPars->nConfLimit, pPars->fVerbose, &Status ); {
vCore = Vta_ManUnsatCore( Vga_ManGetOutLit(p, f), p->vCla2Var, p->pSat, pPars->nConfLimit, pPars->fVerbose, &Status, NULL );
assert( (vCore != NULL) == (Status == 1) ); assert( (vCore != NULL) == (Status == 1) );
if ( Status == -1 ) // resource limit is reached if ( Status == -1 ) // resource limit is reached
break; goto finish;
if ( vCore != NULL ) if ( vCore != NULL )
{
// rollback and add the core
// return and double check
break; break;
} assert( Status == 0 );
pCex = Vta_ManRefineAbstraction( p ); pCex = Vta_ManRefineAbstraction( p, f );
} goto finish;
while ( pCex == NULL ); }
if ( Status == -1 ) // resource limit is reached assert( Status == 1 );
break; // valid core is obtained
*/ Vta_ManUnsatCoreRemap( p, vCore );
} Vec_IntSort( vCore, 0 );
if ( pCex != NULL ) // update the SAT solver
{ sat_solver2_rollback( p->pSat );
printf( "True CEX is detected.\n" ); // load this timeframe
RetValue = 0; Vga_ManLoadSlice( p, vCore, 0 );
break; Vec_IntFree( vCore );
} }
if ( vCore == NULL ) // run SAT solver
vCore = Vta_ManUnsatCore( Vga_ManGetOutLit(p, f), p->vCla2Var, p->pSat, pPars->nConfLimit, p->pPars->fVerbose, &Status, &nConfls );
if ( p->pPars->fVerbose )
printf( "%6d", nConfls );
assert( (vCore != NULL) == (Status == 1) );
if ( Status == -1 ) // resource limit is reached
goto finish;
if ( Status == 0 )
{ {
printf( "Resource limit is exhausted.\n" ); // make sure, there was no initial abstraction (otherwise, it was invalid)
RetValue = -1; assert( pAig->vObjClasses == NULL && f < p->pPars->nFramesStart );
break; pCex = Vga_ManDeriveCex( p );
} }
// add the core // add the core
Vta_ManUnsatCoreRemap( p, vCore ); Vta_ManUnsatCoreRemap( p, vCore );
// add in direct topological order
Vec_IntSort( vCore, 0 );
Vec_PtrPush( p->vCores, vCore ); Vec_PtrPush( p->vCores, vCore );
// print the result // print the result
if ( p->pPars->fVerbose ) Vta_ManAbsPrintFrame( p, vCore, f+1, p->pPars->fVerbose );
Vta_ManAbsPrintFrame( p, vCore, f+1 );
if ( f == p->pPars->nFramesStart-1 ) if ( f == p->pPars->nFramesStart-1 )
break; break;
} }
finish:
// analize the results // analize the results
if ( pCex == NULL ) if ( pCex == NULL )
{ {
......
...@@ -200,6 +200,8 @@ Vec_Ptr_t * Gia_ManUnrollAbs( Gia_Man_t * p, int nFrames ) ...@@ -200,6 +200,8 @@ Vec_Ptr_t * Gia_ManUnrollAbs( Gia_Man_t * p, int nFrames )
} }
// printf( "\n" ); // printf( "\n" );
} }
// add in reverse topological order
Vec_IntSort( vOne, 1 );
Vec_PtrPush( vFrames, vOne ); Vec_PtrPush( vFrames, vOne );
assert( Vec_IntSize(vOne) <= Size - 1 ); assert( Vec_IntSize(vOne) <= Size - 1 );
} }
......
...@@ -55,11 +55,6 @@ extern void Sat_Solver2PrintStats( FILE * pFile, sat_solver2 * p ); ...@@ -55,11 +55,6 @@ extern void Sat_Solver2PrintStats( FILE * pFile, sat_solver2 * p );
extern int * Sat_Solver2GetModel( sat_solver2 * p, int * pVars, int nVars ); extern int * Sat_Solver2GetModel( sat_solver2 * p, int * pVars, int nVars );
extern void Sat_Solver2DoubleClauses( sat_solver2 * p, int iVar ); extern void Sat_Solver2DoubleClauses( sat_solver2 * p, int iVar );
// trace recording
extern void sat_solver2TraceStart( sat_solver2 * pSat, char * pName );
extern void sat_solver2TraceStop( sat_solver2 * pSat );
extern void sat_solver2TraceWrite( sat_solver2 * pSat, int * pBeg, int * pEnd, int fRoot );
// global variables // global variables
extern int var_is_partA (sat_solver2* s, int v); extern int var_is_partA (sat_solver2* s, int v);
extern void var_set_partA(sat_solver2* s, int v, int partA); extern void var_set_partA(sat_solver2* s, int v, int partA);
...@@ -257,7 +252,7 @@ static inline int sat_solver2_set_random(sat_solver2* s, int fNotUseRandom) ...@@ -257,7 +252,7 @@ static inline int sat_solver2_set_random(sat_solver2* s, int fNotUseRandom)
return fNotUseRandomOld; return fNotUseRandomOld;
} }
static inline int sat_solver2_bookmark(sat_solver2* s) static inline void sat_solver2_bookmark(sat_solver2* s)
{ {
s->hLearntPivot = veci_size(&s->learnts); s->hLearntPivot = veci_size(&s->learnts);
s->hClausePivot = veci_size(&s->clauses); s->hClausePivot = veci_size(&s->clauses);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment