From f0236d5ac1b6d127354b5dd67aba79735bfceaa2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 10 Oct 2021 14:43:19 -0700 Subject: Experiments with pattern generation. --- src/aig/gia/gia.h | 2 + src/aig/gia/giaPat2.c | 1273 ++++++++++++++++++++++++++++++++++++++++++++++ src/aig/gia/giaSimBase.c | 100 ++++ src/aig/gia/module.make | 1 + 4 files changed, 1376 insertions(+) create mode 100644 src/aig/gia/giaPat2.c (limited to 'src/aig/gia') diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 66ac9e13..fb924ce5 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -622,6 +622,8 @@ static inline void Gia_ObjSetTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * p static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); p->pTravIds[Gia_ObjId(p, pObj)] = p->nTravIds - 1; } static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds); } static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds - 1); } +static inline int Gia_ObjUpdateTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsTravIdCurrent(p, pObj) ) return 1; Gia_ObjSetTravIdCurrent(p, pObj); return 0; } +static inline int Gia_ObjUpdateTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsTravIdPrevious(p, pObj) ) return 1; Gia_ObjSetTravIdPrevious(p, pObj); return 0; } static inline void Gia_ObjSetTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds; } static inline void Gia_ObjSetTravIdPreviousId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds - 1; } static inline int Gia_ObjIsTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); } diff --git a/src/aig/gia/giaPat2.c b/src/aig/gia/giaPat2.c new file mode 100644 index 00000000..3151ed22 --- /dev/null +++ b/src/aig/gia/giaPat2.c @@ -0,0 +1,1273 @@ +/**CFile**************************************************************** + + FileName [giaPat2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Pattern generation.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaPat2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "misc/vec/vecHsh.h" +#include "sat/cnf/cnf.h" +#include "sat/bsat/satStore.h" +#include "misc/util/utilTruth.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Min_Man_t_ Min_Man_t; +struct Min_Man_t_ +{ + int nCis; + int nCos; + int FirstAndLit; + int FirstCoLit; + Vec_Int_t vFans; + Vec_Str_t vValsN; + Vec_Str_t vValsL; + Vec_Int_t vVis; + Vec_Int_t vPat; +}; + +static inline int Min_ManCiNum( Min_Man_t * p ) { return p->nCis; } +static inline int Min_ManCoNum( Min_Man_t * p ) { return p->nCos; } +static inline int Min_ManObjNum( Min_Man_t * p ) { return Vec_IntSize(&p->vFans) >> 1; } +static inline int Min_ManAndNum( Min_Man_t * p ) { return Min_ManObjNum(p) - p->nCis - p->nCos - 1; } + +static inline int Min_ManCi( Min_Man_t * p, int i ) { return 1 + i; } +static inline int Min_ManCo( Min_Man_t * p, int i ) { return Min_ManObjNum(p) - Min_ManCoNum(p) + i; } + +static inline int Min_ObjIsCi( Min_Man_t * p, int i ) { return i > 0 && i <= Min_ManCiNum(p); } +static inline int Min_ObjIsNode( Min_Man_t * p, int i ) { return i > Min_ManCiNum(p) && i < Min_ManObjNum(p) - Min_ManCoNum(p); } +static inline int Min_ObjIsAnd( Min_Man_t * p, int i ) { return Min_ObjIsNode(p, i) && Vec_IntEntry(&p->vFans, 2*i) < Vec_IntEntry(&p->vFans, 2*i+1); } +static inline int Min_ObjIsXor( Min_Man_t * p, int i ) { return Min_ObjIsNode(p, i) && Vec_IntEntry(&p->vFans, 2*i) > Vec_IntEntry(&p->vFans, 2*i+1); } +static inline int Min_ObjIsBuf( Min_Man_t * p, int i ) { return Min_ObjIsNode(p, i) && Vec_IntEntry(&p->vFans, 2*i) ==Vec_IntEntry(&p->vFans, 2*i+1); } +static inline int Min_ObjIsCo( Min_Man_t * p, int i ) { return i >= Min_ManObjNum(p) - Min_ManCoNum(p) && i < Min_ManObjNum(p); } + +static inline int Min_ObjLit( Min_Man_t * p, int i, int n ) { return Vec_IntEntry(&p->vFans, i + i + n); } +static inline int Min_ObjLit0( Min_Man_t * p, int i ) { return Vec_IntEntry(&p->vFans, i + i + 0); } +static inline int Min_ObjLit1( Min_Man_t * p, int i ) { return Vec_IntEntry(&p->vFans, i + i + 1); } +static inline int Min_ObjCioId( Min_Man_t * p, int i ) { assert( i && !Min_ObjIsNode(p, i) ); return Min_ObjLit1(p, i); } + +static inline int Min_ObjFan0( Min_Man_t * p, int i ) { return Abc_Lit2Var( Min_ObjLit0(p, i) ); } +static inline int Min_ObjFan1( Min_Man_t * p, int i ) { return Abc_Lit2Var( Min_ObjLit1(p, i) ); } + +static inline int Min_ObjFanC0( Min_Man_t * p, int i ) { return Abc_LitIsCompl( Min_ObjLit0(p, i) ); } +static inline int Min_ObjFanC1( Min_Man_t * p, int i ) { return Abc_LitIsCompl( Min_ObjLit1(p, i) ); } + +static inline char Min_ObjValN( Min_Man_t * p, int i ) { return Vec_StrEntry(&p->vValsN, i); } +static inline void Min_ObjSetValN( Min_Man_t * p, int i, char v ){ Vec_StrWriteEntry(&p->vValsN, i, v); } + +static inline char Min_LitValL( Min_Man_t * p, int i ) { return Vec_StrEntry(&p->vValsL, i); } +static inline void Min_LitSetValL( Min_Man_t * p, int i, char v ){ assert(v==0 || v==1); Vec_StrWriteEntry(&p->vValsL, i, v); Vec_StrWriteEntry(&p->vValsL, i^1, (char)!v); Vec_IntPush(&p->vVis, Abc_Lit2Var(i)); } +static inline void Min_ObjCleanValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] = 0x0202; } +static inline void Min_ObjMarkValL( Min_Man_t * p, int i ) { ((short *)Vec_StrArray(&p->vValsL))[i] |= 0x0404; } + +static inline int Min_LitIsCi( Min_Man_t * p, int v ) { return v > 1 && v < p->FirstAndLit; } +static inline int Min_LitIsNode( Min_Man_t * p, int v ) { return v >= p->FirstAndLit && v < p->FirstCoLit; } +static inline int Min_LitIsCo( Min_Man_t * p, int v ) { return v >= p->FirstCoLit; } + +static inline int Min_LitIsAnd( int v, int v0, int v1 ) { return Abc_LitIsCompl(v) ^ (v0 < v1); } +static inline int Min_LitIsXor( int v, int v0, int v1 ) { return Abc_LitIsCompl(v) ^ (v0 > v1); } +static inline int Min_LitIsBuf( int v, int v0, int v1 ) { return v0 == v1; } + +static inline int Min_LitFan( Min_Man_t * p, int v ) { return Vec_IntEntry(&p->vFans, v); } +static inline int Min_LitFanC( Min_Man_t * p, int v ) { return Abc_LitIsCompl( Min_LitFan(p, v) ); } + +static inline void Min_ManStartValsN( Min_Man_t * p ) { Vec_StrGrow(&p->vValsN, Vec_IntCap(&p->vFans)/2); Vec_StrFill(&p->vValsN, Min_ManObjNum(p), 2); } +static inline void Min_ManStartValsL( Min_Man_t * p ) { Vec_StrGrow(&p->vValsL, Vec_IntCap(&p->vFans)); Vec_StrFill(&p->vValsL, Vec_IntSize(&p->vFans), 2); } +static inline int Min_ManCheckCleanValsL( Min_Man_t * p ) { int i; char c; Vec_StrForEachEntry( &p->vValsL, c, i ) if ( c != 2 ) return 0; return 1; } +static inline void Min_ManCleanVisitedValL( Min_Man_t * p ) { int i, iObj; Vec_IntForEachEntry(&p->vVis, iObj, i) Min_ObjCleanValL(p, iObj); Vec_IntClear(&p->vVis); } + + +#define Min_ManForEachObj( p, i ) \ + for ( i = 0; i < Min_ManObjNum(p); i++ ) +#define Min_ManForEachCi( p, i ) \ + for ( i = 1; i <= Min_ManCiNum(p); i++ ) +#define Min_ManForEachCo( p, i ) \ + for ( i = Min_ManObjNum(p) - Min_ManCoNum(p); i < Min_ManObjNum(p); i++ ) +#define Min_ManForEachAnd( p, i ) \ + for ( i = 1 + Min_ManCiNum(p); i < Min_ManObjNum(p) - Min_ManCoNum(p); i++ ) + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Min_Man_t * Min_ManStart( int nObjMax ) +{ + Min_Man_t * p = ABC_CALLOC( Min_Man_t, 1 ); + Vec_IntGrow( &p->vFans, nObjMax ); + Vec_IntPushTwo( &p->vFans, -1, -1 ); + return p; +} +static inline void Min_ManStop( Min_Man_t * p ) +{ + Vec_IntErase( &p->vFans ); + Vec_StrErase( &p->vValsN ); + Vec_StrErase( &p->vValsL ); + Vec_IntErase( &p->vVis ); + Vec_IntErase( &p->vPat ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Min_ManAppendObj( Min_Man_t * p, int iLit0, int iLit1 ) +{ + int iLit = Vec_IntSize(&p->vFans); + Vec_IntPushTwo( &p->vFans, iLit0, iLit1 ); + return iLit; +} +static inline int Min_ManAppendCi( Min_Man_t * p ) +{ + p->nCis++; + p->FirstAndLit = Vec_IntSize(&p->vFans) + 2; + return Min_ManAppendObj( p, 0, p->nCis-1 ); +} +static inline int Min_ManAppendCo( Min_Man_t * p, int iLit0 ) +{ + p->nCos++; + if ( p->FirstCoLit == 0 ) + p->FirstCoLit = Vec_IntSize(&p->vFans); + return Min_ManAppendObj( p, iLit0, p->nCos-1 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_ManFromGia_rec( Min_Man_t * pNew, Gia_Man_t * p, int iObj ) +{ + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj) ); + Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj) ); + pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} +Min_Man_t * Min_ManFromGia( Gia_Man_t * p, Vec_Int_t * vOuts ) +{ + Gia_Obj_t * pObj; int i; + Min_Man_t * pNew = Min_ManStart( Gia_ManObjNum(p) ); + Gia_ManFillValue(p); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Min_ManAppendCi( pNew ); + if ( vOuts == NULL ) + { + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFaninLit0(pObj, i), Gia_ObjFaninLit1(pObj, i) ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Min_ManAppendCo( pNew, Gia_ObjFaninLit0p(p, pObj) ); + } + else + { + Gia_ManForEachCoVec( vOuts, p, pObj, i ) + Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId0p(p, pObj) ); + Gia_ManForEachCoVec( vOuts, p, pObj, i ) + Min_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + return pNew; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline char Min_XsimNot( char Val ) +{ + if ( Val < 2 ) + return Val ^ 1; + return 2; +} +static inline char Min_XsimXor( char Val0, char Val1 ) +{ + if ( Val0 < 2 && Val1 < 2 ) + return Val0 ^ Val1; + return 2; +} +static inline char Min_XsimAnd( char Val0, char Val1 ) +{ + if ( Val0 == 0 || Val1 == 0 ) + return 0; + if ( Val0 == 1 && Val1 == 1 ) + return 1; + return 2; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char Min_LitVerify_rec( Min_Man_t * p, int iLit ) +{ + char Val = Min_LitValL(p, iLit); + if ( Val == 2 && Min_LitIsNode(p, iLit) ) // unassigned + { + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitVerify_rec( p, iLit0 ); + char Val1 = Min_LitVerify_rec( p, iLit1 ); + assert( Min_LitIsNode(p, iLit) ); // internal node + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + } + return Val; +} +char Min_LitVerify( Min_Man_t * p, int iLit, Vec_Int_t * vLits ) +{ + int i, Entry; char Res; + if ( iLit < 2 ) return 1; + assert( !Min_LitIsCo(p, iLit) ); + //assert( Min_ManCheckCleanValsL(p) ); + assert( Vec_IntSize(&p->vVis) == 0 ); + Vec_IntForEachEntry( vLits, Entry, i ) + Min_LitSetValL( p, Entry, 1 ); // ms notation + Res = Min_LitVerify_rec( p, iLit ); + Min_ManCleanVisitedValL( p ); + return Res; +} + +void Min_LitMinimize( Min_Man_t * p, int iLit, Vec_Int_t * vLits ) +{ + int i, iObj, iTemp; char Res; + Vec_IntClear( &p->vPat ); + if ( iLit < 2 ) return; + assert( !Min_LitIsCo(p, iLit) ); + //assert( Min_ManCheckCleanValsL(p) ); + assert( Vec_IntSize(&p->vVis) == 0 ); + Vec_IntForEachEntry( vLits, iTemp, i ) + Min_LitSetValL( p, iTemp, 1 ); // ms notation + Res = Min_LitVerify_rec( p, iLit ); + assert( Res == 1 ); + Min_ObjMarkValL( p, Abc_Lit2Var(iLit) ); + Vec_IntForEachEntryReverse( &p->vVis, iObj, i ) + { + int iLit = Abc_Var2Lit( iObj, 0 ); + int Value = Min_LitValL(p, iLit); + if ( Value >= 4 ) + { + if ( Min_LitIsCi(p, iLit) ) + Vec_IntPush( &p->vPat, Abc_LitNotCond(iLit, !(Value&1)) ); + else + { + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL( p, iLit0 ); + char Val1 = Min_LitValL( p, iLit1 ); + if ( Value == 5 ) // value == 1 + { + assert( (Val0&1) && (Val1&1) ); + Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) ); + Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) ); + } + else // value == 0 + { + int Zero0 = !(Val0&3); + int Zero1 = !(Val1&3); + assert( Zero0 || Zero1 ); + if ( Zero0 && !Zero1 ) + Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) ); + else if ( !Zero0 && Zero1 ) + Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) ); + else if ( Val0 == 4 && Val1 != 4 ) + Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) ); + else if ( Val1 == 4 && Val1 != 4 ) + Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) ); + else if ( Abc_Random(0) & 1 ) + Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) ); + else + Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) ); + } + } + } + Min_ObjCleanValL( p, Abc_Lit2Var(iLit) ); + } + Vec_IntClear( &p->vVis ); + //Min_ManCleanVisitedValL( p ); + //assert( Min_LitVerify(p, iLit, &p->vPat) == 1 ); + assert( Vec_IntSize(&p->vPat) <= Vec_IntSize(vLits) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline char Min_LitIsImplied1( Min_Man_t * p, int iLit ) +{ + char Val = 2; + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + assert( Min_LitIsNode(p, iLit) ); // internal node + assert( Min_LitValL(p, iLit) == 2 ); // unassigned + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + return Val; +} +static inline char Min_LitIsImplied2( Min_Man_t * p, int iLit ) +{ + char Val = 2; + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + assert( Min_LitIsNode(p, iLit) ); // internal node + assert( Min_LitValL(p, iLit) == 2 ); // unassigned + if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) + Val0 = Min_LitIsImplied1(p, iLit0); + if ( Val1 == 2 && Min_LitIsNode(p, iLit1) ) + Val1 = Min_LitIsImplied1(p, iLit1); + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + return Val; +} +static inline char Min_LitIsImplied3( Min_Man_t * p, int iLit ) +{ + char Val = 2; + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + assert( Min_LitIsNode(p, iLit) ); // internal node + assert( Min_LitValL(p, iLit) == 2 ); // unassigned + if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) + Val0 = Min_LitIsImplied2(p, iLit0); + if ( Val1 == 2 && Min_LitIsNode(p, iLit1) ) + Val1 = Min_LitIsImplied2(p, iLit1); + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + return Val; +} +static inline char Min_LitIsImplied4( Min_Man_t * p, int iLit ) +{ + char Val = 2; + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + assert( Min_LitIsNode(p, iLit) ); // internal node + assert( Min_LitValL(p, iLit) == 2 ); // unassigned + if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) + Val0 = Min_LitIsImplied3(p, iLit0); + if ( Val1 == 2 && Min_LitIsNode(p, iLit1) ) + Val1 = Min_LitIsImplied3(p, iLit1); + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + return Val; +} +static inline char Min_LitIsImplied5( Min_Man_t * p, int iLit ) +{ + char Val = 2; + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + assert( Min_LitIsNode(p, iLit) ); // internal node + assert( Min_LitValL(p, iLit) == 2 ); // unassigned + if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) + Val0 = Min_LitIsImplied4(p, iLit0); + if ( Val1 == 2 && Min_LitIsNode(p, iLit1) ) + Val1 = Min_LitIsImplied4(p, iLit1); + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + return Val; +} + +// this recursive procedure is about 10% slower +char Min_LitIsImplied_rec( Min_Man_t * p, int iLit, int Depth ) +{ + char Val = 2; + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + assert( Depth > 0 ); + assert( Min_LitIsNode(p, iLit) ); // internal node + assert( Min_LitValL(p, iLit) == 2 ); // unassigned + if ( Depth > 1 && Val0 == 2 && Min_LitIsNode(p, iLit0) ) + { + Val0 = Min_LitIsImplied_rec(p, iLit0, Depth-1); + Val1 = Min_LitValL(p, iLit1); + } + if ( Depth > 1 && Val1 == 2 && Min_LitIsNode(p, iLit1) ) + { + Val1 = Min_LitIsImplied_rec(p, iLit1, Depth-1); + Val0 = Min_LitValL(p, iLit0); + } + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + Val = Min_XsimXor( Val0, Val1 ); + else + Val = Min_XsimAnd( Val0, Val1 ); + if ( Val < 2 ) + { + Val ^= Abc_LitIsCompl(iLit); + Min_LitSetValL( p, iLit, Val ); + } + return Val; +} +int Min_LitJustify_rec( Min_Man_t * p, int iLit ) +{ + int Res = 1, LitValue = !Abc_LitIsCompl(iLit); + int Val = (int)Min_LitValL(p, iLit); + if ( Val < 2 ) // assigned + return Val == LitValue; + // unassigned + if ( Min_LitIsCi(p, iLit) ) + Vec_IntPush( &p->vPat, iLit ); // ms notation + else + { + int iLit0 = Min_LitFan(p, iLit); + int iLit1 = Min_LitFan(p, iLit^1); + char Val0 = Min_LitValL(p, iLit0); + char Val1 = Min_LitValL(p, iLit1); + if ( Min_LitIsXor(iLit, iLit0, iLit1) ) + { + if ( Val0 < 2 && Val1 < 2 ) + Res = LitValue == (Val0 ^ Val1); + else if ( Val0 < 2 ) + Res = Min_LitJustify_rec(p, iLit1^Val0^!LitValue); + else if ( Val1 < 2 ) + Res = Min_LitJustify_rec(p, iLit0^Val1^!LitValue); + else if ( Abc_Random(0) & 1 ) + Res = Min_LitJustify_rec(p, iLit0) && Min_LitJustify_rec(p, iLit1^ LitValue); + else + Res = Min_LitJustify_rec(p, iLit0^1) && Min_LitJustify_rec(p, iLit1^!LitValue); + assert( !Res || LitValue == Min_XsimXor(Min_LitValL(p, iLit0), Min_LitValL(p, iLit1)) ); + } + else if ( LitValue ) // value 1 + { + if ( Val0 == 0 || Val1 == 0 ) + Res = 0; + else if ( Val0 == 1 && Val1 == 1 ) + Res = 1; + else if ( Val0 == 1 ) + Res = Min_LitJustify_rec(p, iLit1); + else if ( Val1 == 1 ) + Res = Min_LitJustify_rec(p, iLit0); + else + Res = Min_LitJustify_rec(p, iLit0) && Min_LitJustify_rec(p, iLit1); + assert( !Res || 1 == Min_XsimAnd(Min_LitValL(p, iLit0), Min_LitValL(p, iLit1)) ); + } + else // value 0 + { +/* + int Depth = 3; + if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) + { + Val0 = Min_LitIsImplied_rec(p, iLit0, Depth); + Val1 = Min_LitValL(p, iLit1); + } + if ( Val1 == 2 && Min_LitIsNode(p, iLit1) ) + { + Val1 = Min_LitIsImplied_rec(p, iLit1, Depth); + Val0 = Min_LitValL(p, iLit0); + } +*/ + if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) + { + Val0 = Min_LitIsImplied3(p, iLit0); + Val1 = Min_LitValL(p, iLit1); + } + if ( Val1 == 2 && Min_LitIsNode(p, iLit1) ) + { + Val1 = Min_LitIsImplied3(p, iLit1); + Val0 = Min_LitValL(p, iLit0); + } + if ( Val0 == 0 || Val1 == 0 ) + Res = 1; + else if ( Val0 == 1 && Val1 == 1 ) + Res = 0; + else if ( Val0 == 1 ) + Res = Min_LitJustify_rec(p, iLit1^1); + else if ( Val1 == 1 ) + Res = Min_LitJustify_rec(p, iLit0^1); + else if ( Abc_Random(0) & 1 ) + //else if ( (p->Random >> (iLit & 0x1F)) & 1 ) + Res = Min_LitJustify_rec(p, iLit0^1); + else + Res = Min_LitJustify_rec(p, iLit1^1); + //Val0 = Min_LitValL(p, iLit0); + //Val1 = Min_LitValL(p, iLit1); + assert( !Res || 0 == Min_XsimAnd(Min_LitValL(p, iLit0), Min_LitValL(p, iLit1)) ); + } + } + if ( Res ) + Min_LitSetValL( p, iLit, 1 ); + return Res; +} +int Min_LitJustify( Min_Man_t * p, int iLit ) +{ + int Res, fCheck = 1; + Vec_IntClear( &p->vPat ); + if ( iLit < 2 ) return 1; + assert( !Min_LitIsCo(p, iLit) ); + //assert( Min_ManCheckCleanValsL(p) ); + assert( Vec_IntSize(&p->vVis) == 0 ); + //p->Random = Abc_Random(0); + Res = Min_LitJustify_rec( p, iLit ); + Min_ManCleanVisitedValL( p ); + if ( Res ) + { + Vec_IntSort( &p->vPat, 0 ); + if ( fCheck && Min_LitVerify(p, iLit, &p->vPat) != 1 ) + printf( "Verification FAILED for literal %d.\n", iLit ); + //else + // printf( "Verification succeeded for literal %d.\n", iLit ); + } + //else + // printf( "Could not justify literal %d.\n", iLit ); + return Res; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Min_TargGenerateCexes( Min_Man_t * p, Vec_Int_t * vCoErrs, int nCexes, int nCexesStop, int * pnComputed, int fVerbose ) +{ + abctime clk = Abc_Clock(); + int t, iObj, Count = 0, CountPos = 0, CountPosSat = 0, nRuns[2] = {0}, nCountCexes[2] = {0}; + Vec_Int_t * vPats = Vec_IntAlloc( 1000 ); + Vec_Int_t * vPatBest = Vec_IntAlloc( Min_ManCiNum(p) ); + Hsh_VecMan_t * pHash = Hsh_VecManStart( 10000 ); + Min_ManForEachCo( p, iObj ) if ( Min_ObjLit0(p, iObj) > 1 ) + { + int nCexesGenSim0 = 0; + int nCexesGenSim = 0; + int nCexesGenSat = 0; + if ( vCoErrs && Vec_IntEntry(vCoErrs, Min_ObjCioId(p, iObj)) >= nCexesStop ) + continue; + //printf( "%d ", i ); + for ( t = 0; t < nCexes; t++ ) + { + nRuns[0]++; + if ( Min_LitJustify( p, Min_ObjLit0(p, iObj) ) ) + { + int Before, After; + assert( Vec_IntSize(&p->vPat) > 0 ); + //printf( "%d ", Vec_IntSize(vPat) ); + Vec_IntClear( vPatBest ); + if ( 1 ) // no minimization + Vec_IntAppend( vPatBest, &p->vPat ); + else + { +/* + for ( k = 0; k < 10; k++ ) + { + Vec_IntClear( vPat2 ); + Gia_ManIncrementTravId( p ); + Cexes_MinimizePattern_rec( p, Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), vPat2 ); + assert( Vec_IntSize(vPat2) <= Vec_IntSize(vPat) ); + if ( Vec_IntSize(vPatBest) == 0 || Vec_IntSize(vPatBest) > Vec_IntSize(vPat2) ) + { + Vec_IntClear( vPatBest ); + Vec_IntAppend( vPatBest, vPat2 ); + } + //printf( "%d ", Vec_IntSize(vPat2) ); + } +*/ + } + + //Gia_CexVerify( p, Gia_ObjFaninId0p(p, pObj), !Gia_ObjFaninC0(pObj), vPatBest ); + //printf( "\n" ); + Before = Hsh_VecSize( pHash ); + Vec_IntSort( vPatBest, 0 ); + Hsh_VecManAdd( pHash, vPatBest ); + After = Hsh_VecSize( pHash ); + if ( Before != After ) + { + Vec_IntPush( vPats, Min_ObjCioId(p, iObj) ); + Vec_IntPush( vPats, Vec_IntSize(vPatBest) ); + Vec_IntAppend( vPats, vPatBest ); + nCexesGenSim++; + } + nCexesGenSim0++; + if ( nCexesGenSim0 > nCexesGenSim*10 ) + { + printf( "**** Skipping output %d (out of %d)\n", Min_ObjCioId(p, iObj), Min_ManCoNum(p) ); + break; + } + } + if ( nCexesGenSim == nCexesStop ) + break; + } + //printf( "(%d %d) ", nCexesGenSim0, nCexesGenSim ); + //printf( "%d ", t/nCexesGenSim ); + + //printf( "The number of CEXes = %d\n", nCexesGen ); + //if ( fVerbose ) + // printf( "%d ", nCexesGen ); + nCountCexes[0] += nCexesGenSim; + nCountCexes[1] += nCexesGenSat; + Count += nCexesGenSim + nCexesGenSat; + CountPos++; + + if ( nCexesGenSim0 == 0 && t == nCexes ) + printf( "#### Output %d (out of %d)\n", Min_ObjCioId(p, iObj), Min_ManCoNum(p) ); + } + //printf( "\n" ); + if ( fVerbose ) + printf( "\n" ); + if ( fVerbose ) + printf( "Got %d unique CEXes using %d sim (%d) and %d SAT (%d) runs (ave size %.1f). PO = %d ErrPO = %d SatPO = %d ", + Count, nRuns[0], nCountCexes[0], nRuns[1], nCountCexes[1], + 1.0*Vec_IntSize(vPats)/Abc_MaxInt(1, Count)-2, Min_ManCoNum(p), CountPos, CountPosSat ); + if ( fVerbose ) + Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); + Hsh_VecManStop( pHash ); + Vec_IntFree( vPatBest ); + *pnComputed = Count; + return vPats; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Min_ManTest3( Gia_Man_t * p, Vec_Int_t * vCoErrs ) +{ + int fXor = 0; + int nComputed; + Vec_Int_t * vPats; + Gia_Man_t * pXor = fXor ? Gia_ManDupMuxes(p, 1) : NULL; + Min_Man_t * pNew = Min_ManFromGia( fXor ? pXor : p, NULL ); + Gia_ManStopP( &pXor ); + Min_ManStartValsL( pNew ); + //Vec_IntFill( vCoErrs, Vec_IntSize(vCoErrs), 0 ); + //vPats = Min_TargGenerateCexes( pNew, vCoErrs, 10000, 10, &nComputed, 1 ); + vPats = Min_TargGenerateCexes( pNew, vCoErrs, 10000, 10, &nComputed, 1 ); + Vec_IntFree( vPats ); + Min_ManStop( pNew ); +} +void Min_ManTest4( Gia_Man_t * p ) +{ + Vec_Int_t * vCoErrs = Vec_IntStartNatural( Gia_ManCoNum(p) ); + Min_ManTest3(p, vCoErrs); + Vec_IntFree( vCoErrs ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDupCones2CollectPis_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vMap ) +{ + Gia_Obj_t * pObj; + if ( Gia_ObjUpdateTravIdCurrentId(p, iObj) ) + return; + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ManDupCones2CollectPis_rec( p, Gia_ObjFaninId0(pObj, iObj), vMap ); + Gia_ManDupCones2CollectPis_rec( p, Gia_ObjFaninId1(pObj, iObj), vMap ); + } + else if ( Gia_ObjIsCi(pObj) ) + Vec_IntPush( vMap, iObj ); + else assert( 0 ); +} +void Gia_ManDupCones2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( Gia_ObjIsCi(pObj) || Gia_ObjUpdateTravIdCurrent(p, pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManDupCones2_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManDupCones2_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} +Gia_Man_t * Gia_ManDupCones2( Gia_Man_t * p, int * pOuts, int nOuts, Vec_Int_t * vMap ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; int i; + Vec_IntClear( vMap ); + Gia_ManIncrementTravId( p ); + for ( i = 0; i < nOuts; i++ ) + Gia_ManDupCones2CollectPis_rec( p, Gia_ManCoDriverId(p, pOuts[i]), vMap ); + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachObjVec( vMap, p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManIncrementTravId( p ); + for ( i = 0; i < nOuts; i++ ) + Gia_ManDupCones2_rec( pNew, p, Gia_ObjFanin0(Gia_ManCo(p, pOuts[i])) ); + for ( i = 0; i < nOuts; i++ ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(Gia_ManCo(p, pOuts[i])) ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Min_ManRemoveItem( Vec_Wec_t * vCexes, int iItem, int iFirst, int iLimit ) +{ + Vec_Int_t * vLevel, * vLevel0 = Vec_WecEntry(vCexes, iItem); int i; + assert( iFirst <= iItem && iItem < iLimit ); + Vec_WecForEachLevelReverseStartStop( vCexes, vLevel, i, iLimit, iFirst ) + if ( Vec_IntSize(vLevel) > 0 ) + break; + assert( iFirst <= i && iItem <= i ); + Vec_IntClear( vLevel0 ); + if ( iItem < i ) + ABC_SWAP( Vec_Int_t, *vLevel0, *vLevel ); + return -1; +} +int Min_ManAccumulate( Vec_Wec_t * vCexes, int iFirst, int iLimit, Vec_Int_t * vCex ) +{ + Vec_Int_t * vLevel; int i, nCommon, nDiff = 0; + Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iFirst, iLimit ) + { + if ( Vec_IntSize(vLevel) == 0 ) + { + Vec_IntAppend(vLevel, vCex); + return nDiff+1; + } + nCommon = Vec_IntTwoCountCommon( vLevel, vCex ); + if ( nCommon == Vec_IntSize(vLevel) ) // ignore vCex + return nDiff; + if ( nCommon == Vec_IntSize(vCex) ) // remove vLevel + nDiff += Min_ManRemoveItem( vCexes, i, iFirst, iLimit ); + } + assert( 0 ); + return ABC_INFINITY; +} +int Min_ManCountSize( Vec_Wec_t * vCexes, int iFirst, int iLimit ) +{ + Vec_Int_t * vLevel; int i, nTotal = 0; + Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iFirst, iLimit ) + nTotal += Vec_IntSize(vLevel) > 0; + return nTotal; +} +Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTries, int nMinCexes, Vec_Int_t * vStats[3], int fUseSim, int fUseSat, int fVerbose ) +{ + Vec_Int_t * vOuts = vOuts0 ? vOuts0 : Vec_IntStartNatural( Gia_ManCoNum(p) ); + Min_Man_t * pNew = Min_ManFromGia( p, vOuts ); + Vec_Wec_t * vCexes = Vec_WecStart( Vec_IntSize(vOuts) * nMinCexes ); + Vec_Int_t * vPatBest = Vec_IntAlloc( 100 ); + Vec_Int_t * vLits = Vec_IntAlloc( 100 ); + Gia_Obj_t * pObj; int i, iObj, nOuts = 0, nSimOuts = 0, nSatOuts = 0; + vStats[0] = Vec_IntAlloc( Vec_IntSize(vOuts) ); // total calls + vStats[1] = Vec_IntAlloc( Vec_IntSize(vOuts) ); // successful calls + SAT runs + vStats[2] = Vec_IntAlloc( Vec_IntSize(vOuts) ); // results + Min_ManStartValsL( pNew ); + Min_ManForEachCo( pNew, iObj ) + { + int nAllCalls = 0; + int nGoodCalls = 0; + int nCurrCexes = 0; + if ( fUseSim && Min_ObjLit0(pNew, iObj) >= 2 ) + { + while ( nAllCalls++ < nMaxTries ) + { + if ( Min_LitJustify( pNew, Min_ObjLit0(pNew, iObj) ) ) + { + Vec_IntClearAppend( vLits, &pNew->vPat ); + Vec_IntClearAppend( vPatBest, &pNew->vPat ); + if ( 1 ) // minimization + { + //printf( "%d -> ", Vec_IntSize(vPatBest) ); + for ( i = 0; i < 10; i++ ) + { + Min_LitMinimize( pNew, Min_ObjLit0(pNew, iObj), vLits ); + if ( Vec_IntSize(vPatBest) > Vec_IntSize(&pNew->vPat) ) + Vec_IntClearAppend( vPatBest, &pNew->vPat ); + } + //printf( "%d ", Vec_IntSize(vPatBest) ); + } + assert( Vec_IntSize(vPatBest) > 0 ); + nCurrCexes += Min_ManAccumulate( vCexes, nOuts*nMinCexes, (nOuts+1)*nMinCexes, vPatBest ); + nGoodCalls++; + } + if ( nCurrCexes == nMinCexes || nGoodCalls > 10*nCurrCexes ) + break; + } + nSimOuts++; + } + assert( nCurrCexes <= nMinCexes ); + assert( nCurrCexes == Min_ManCountSize(vCexes, nOuts*nMinCexes, (nOuts+1)*nMinCexes) ); + Vec_IntPush( vStats[0], nAllCalls ); + Vec_IntPush( vStats[1], nGoodCalls ); + Vec_IntPush( vStats[2], nCurrCexes ); + nOuts++; + } + assert( Vec_IntSize(vOuts) == nOuts ); + assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[0]) ); + assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[1]) ); + assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[2]) ); + + if ( fUseSat ) + Gia_ManForEachCoVec( vOuts, p, pObj, i ) + { + if ( Vec_IntEntry(vStats[2], i) >= nMinCexes || Vec_IntEntry(vStats[1], i) > 10*Vec_IntEntry(vStats[2], i) ) + continue; + { + int iObj = Min_ManCo(pNew, i); + int Index = Gia_ObjCioId(pObj); + Vec_Int_t * vMap = Vec_IntAlloc( 100 ); + Gia_Man_t * pCon = Gia_ManDupCones2( p, &Index, 1, vMap ); + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCon, 8, 0, 0, 0, 0 ); + sat_solver* pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); + int Lit = Abc_Var2Lit( 1, 0 ); + int status = sat_solver_addclause( pSat, &Lit, &Lit+1 ); + int nAllCalls = 0; + int nCurrCexes = Vec_IntEntry(vStats[2], i); + //Gia_AigerWrite( pCon, "temp_miter.aig", 0, 0, 0 ); + if ( status == l_True ) + { + nSatOuts++; + //printf( "Running SAT for output %d\n", i ); + if ( Min_ObjLit0(pNew, iObj) >= 2 ) + { + while ( nAllCalls++ < 100 ) + { + int v, iVar = pCnf->nVars - Gia_ManPiNum(pCon), nVars = Gia_ManPiNum(pCon); + sat_solver_randomize( pSat, iVar, nVars ); + status = sat_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 ); + assert( status == l_True ); + Vec_IntClear( vLits ); + for ( v = 0; v < nVars; v++ ) + Vec_IntPush( vLits, Abc_Var2Lit(Vec_IntEntry(vMap, v), !sat_solver_var_value(pSat, iVar + v)) ); + Min_LitMinimize( pNew, Min_ObjLit0(pNew, iObj), vLits ); + Vec_IntClearAppend( vPatBest, &pNew->vPat ); + if ( 1 ) // minimization + { + //printf( "%d -> ", Vec_IntSize(vPatBest) ); + for ( v = 0; v < 20; v++ ) + { + Min_LitMinimize( pNew, Min_ObjLit0(pNew, iObj), vLits ); + if ( Vec_IntSize(vPatBest) > Vec_IntSize(&pNew->vPat) ) + Vec_IntClearAppend( vPatBest, &pNew->vPat ); + } + //printf( "%d ", Vec_IntSize(vPatBest) ); + } + Vec_IntSort( vPatBest, 0 ); + nCurrCexes += Min_ManAccumulate( vCexes, i*nMinCexes, (i+1)*nMinCexes, vPatBest ); + if ( nCurrCexes == nMinCexes || nAllCalls > 10*nCurrCexes ) + break; + } + } + } + Vec_IntWriteEntry( vStats[0], i, nAllCalls*nMaxTries ); + Vec_IntWriteEntry( vStats[1], i, nAllCalls*nMaxTries ); + Vec_IntWriteEntry( vStats[2], i, nCurrCexes ); + sat_solver_delete( pSat ); + Cnf_DataFree( pCnf ); + Gia_ManStop( pCon ); + Vec_IntFree( vMap ); + } + } + if ( fVerbose ) + printf( "Used simulation for %d and SAT for %d outputs (out of %d).\n", nSimOuts, nSatOuts, nOuts ); + //Vec_WecPrint( vCexes, 0 ); + if ( vOuts != vOuts0 ) + Vec_IntFreeP( &vOuts ); + Min_ManStop( pNew ); + Vec_IntFree( vPatBest ); + Vec_IntFree( vLits ); + return vCexes; +} + +/**Function************************************************************* + + Synopsis [Bit-packing for selected patterns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Min_ManBitPackTry( Vec_Wrd_t * vSimsPi, int nWords, int iPat, Vec_Int_t * vLits ) +{ + int i, Lit; + assert( iPat >= 0 && iPat < 64 * nWords ); + Vec_IntForEachEntry( vLits, Lit, i ) + { + word * pInfo = Vec_WrdEntryP( vSimsPi, nWords * Abc_Lit2Var(Lit-2) ); // Lit is based on ObjId + word * pCare = pInfo + Vec_WrdSize(vSimsPi); + if ( Abc_InfoHasBit( (unsigned *)pCare, iPat ) && + Abc_InfoHasBit( (unsigned *)pInfo, iPat ) == Abc_LitIsCompl(Lit) ) // Lit is in ms notation + return 0; + } + Vec_IntForEachEntry( vLits, Lit, i ) + { + word * pInfo = Vec_WrdEntryP( vSimsPi, nWords * Abc_Lit2Var(Lit-2) ); // Lit is based on ObjId + word * pCare = pInfo + Vec_WrdSize(vSimsPi); + Abc_InfoSetBit( (unsigned *)pCare, iPat ); + if ( Abc_InfoHasBit( (unsigned *)pInfo, iPat ) == Abc_LitIsCompl(Lit) ) // Lit is in ms notation + Abc_InfoXorBit( (unsigned *)pInfo, iPat ); + } + return 1; +} +int Min_ManBitPackOne( Vec_Wrd_t * vSimsPi, int iPat0, int nWords, Vec_Int_t * vLits ) +{ + int iPat, nTotal = 64*nWords; + for ( iPat = iPat0 + 1; iPat != iPat0; iPat = (iPat + 1) % nTotal ) + if ( Min_ManBitPackTry( vSimsPi, nWords, iPat, vLits ) ) + break; + return iPat; +} +Vec_Wrd_t * Min_ManBitPack( Gia_Man_t * p, Vec_Wec_t * vCexes, int fRandom, int nMinCexes, Vec_Int_t * vScores, int fVerbose ) +{ + abctime clk = Abc_Clock(); + int fVeryVerbose = 0; + Vec_Wrd_t * vSimsPi = NULL; + Vec_Int_t * vLevel; + int w, nBits, nTotal = 0, fFailed = ABC_INFINITY; + Vec_Int_t * vOrder = Vec_IntStartNatural( Vec_WecSize(vCexes)/nMinCexes ); + assert( Vec_IntSize(vOrder) == Vec_IntSize(vScores) ); + assert( Vec_WecSize(vCexes)%nMinCexes == 0 ); + Abc_MergeSortCost2Reverse( Vec_IntArray(vOrder), Vec_IntSize(vOrder), Vec_IntArray(vScores) ); + if ( fVerbose ) + printf( "Packing: " ); + //for ( w = 1; fFailed > 100; w++ ) + for ( w = 1; fFailed > 0; w++ ) + { + int i, k, iOut, iPatUsed, iPat = 0; + Vec_WrdFreeP( &vSimsPi ); + vSimsPi = fRandom ? Vec_WrdStartRandom(2 * Gia_ManCiNum(p) * w) : Vec_WrdStart(2 * Gia_ManCiNum(p) * w); + Vec_WrdShrink( vSimsPi, Vec_WrdSize(vSimsPi)/2 ); + Abc_TtClear( Vec_WrdLimit(vSimsPi), Vec_WrdSize(vSimsPi) ); + fFailed = nTotal = 0; + Vec_IntForEachEntry( vOrder, iOut, k ) + Vec_WecForEachLevelStartStop( vCexes, vLevel, i, iOut*nMinCexes, (iOut+1)*nMinCexes ) + { + if ( fVeryVerbose && i%nMinCexes == 0 ) + printf( "\n" ); + if ( Vec_IntSize(vLevel) == 0 ) + continue; + iPatUsed = Min_ManBitPackOne( vSimsPi, iPat, w, vLevel ); + fFailed += iPatUsed == iPat; + iPat = (iPatUsed + 1) % (64*w - 1); + if ( fVeryVerbose ) + printf( "Adding output %3d cex %3d to pattern %3d ", i/nMinCexes, i%nMinCexes, iPatUsed ); + if ( fVeryVerbose ) + Vec_IntPrint( vLevel ); + nTotal++; + } + if ( fVerbose ) + printf( "W = %d (F = %d) ", w, fFailed ); + } + if ( fVerbose ) + printf( "Total = %d\n", nTotal ); + if ( fVerbose ) + { + nBits = Abc_TtCountOnesVec( Vec_WrdLimit(vSimsPi), Vec_WrdSize(vSimsPi) ); + printf( "Bit-packing is using %d words and %d bits. Density =%8.4f %%. ", + Vec_WrdSize(vSimsPi)/Gia_ManCiNum(p), nBits, 100.0*nBits/64/Vec_WrdSize(vSimsPi) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + } + Vec_IntFree( vOrder ); + return vSimsPi; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Patt_ManOutputErrorCoverage( Vec_Wrd_t * vErrors, int nOuts ) +{ + Vec_Int_t * vCounts = Vec_IntAlloc( nOuts ); + int i, nWords = Vec_WrdSize(vErrors)/nOuts; + assert( Vec_WrdSize(vErrors) == nOuts * nWords ); + for ( i = 0; i < nOuts; i++ ) + Vec_IntPush( vCounts, Abc_TtCountOnesVec(Vec_WrdEntryP(vErrors, nWords * i), nWords) ); + return vCounts; +} +Vec_Wrd_t * Patt_ManTransposeErrors( Vec_Wrd_t * vErrors, int nOuts ) +{ + extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut ); + int nWordsIn = Vec_WrdSize(vErrors) / nOuts; + int nWordsOut = Abc_Bit6WordNum(nOuts); + Vec_Wrd_t * vSims1 = Vec_WrdStart( 64*nWordsIn*nWordsOut ); + Vec_Wrd_t * vSims2 = Vec_WrdStart( 64*nWordsIn*nWordsOut ); + assert( Vec_WrdSize(vErrors) == nWordsIn * nOuts ); + Abc_TtCopy( Vec_WrdArray(vSims1), Vec_WrdArray(vErrors), Vec_WrdSize(vErrors), 0 ); + Extra_BitMatrixTransposeP( vSims1, nWordsIn, vSims2, nWordsOut ); + Vec_WrdFree( vSims1 ); + return vSims2; +} +Vec_Int_t * Patt_ManPatternErrorCoverage( Vec_Wrd_t * vErrors, int nOuts ) +{ + int nWords = Vec_WrdSize(vErrors)/nOuts; + Vec_Wrd_t * vErrors2 = Patt_ManTransposeErrors( vErrors, nOuts ); + Vec_Int_t * vPatErrs = Patt_ManOutputErrorCoverage( vErrors2, 64*nWords ); + Vec_WrdFree( vErrors2 ); + return vPatErrs; +} + +#define ERR_REPT_SIZE 32 +void Patt_ManProfileErrors( Vec_Int_t * vOutErrs, Vec_Int_t * vPatErrs ) +{ + int nOuts = Vec_IntSize(vOutErrs); + int nPats = Vec_IntSize(vPatErrs); + int ErrOuts[ERR_REPT_SIZE+1] = {0}; + int ErrPats[ERR_REPT_SIZE+1] = {0}; + int i, Errs, nErrors1 = 0, nErrors2 = 0; + Vec_IntForEachEntry( vOutErrs, Errs, i ) + { + nErrors1 += Errs; + ErrOuts[Errs < ERR_REPT_SIZE ? Errs : ERR_REPT_SIZE]++; + } + Vec_IntForEachEntry( vPatErrs, Errs, i ) + { + nErrors2 += Errs; + ErrPats[Errs < ERR_REPT_SIZE ? Errs : ERR_REPT_SIZE]++; + } + assert( nErrors1 == nErrors2 ); + // errors/error_outputs/error_patterns + //printf( "\nError statistics:\n" ); + printf( "Errors =%6d ", nErrors1 ); + printf( "ErrPOs =%5d (Ave = %5.2f) ", nOuts-ErrOuts[0], 1.0*nErrors1/Abc_MaxInt(1, nOuts-ErrOuts[0]) ); + printf( "Patterns =%5d (Ave = %5.2f) ", nPats, 1.0*nErrors1/nPats ); + printf( "Density =%8.4f %%\n", 100.0*nErrors1/nPats/Abc_MaxInt(1, nOuts-ErrOuts[0]) ); + // how many times each output fails + printf( "Outputs: " ); + for ( i = 0; i <= ERR_REPT_SIZE; i++ ) + if ( ErrOuts[i] ) + printf( "%s%d=%d ", i == ERR_REPT_SIZE? ">" : "", i, ErrOuts[i] ); + printf( "\n" ); + // how many times each patterns fails an output + printf( "Patterns: " ); + for ( i = 0; i <= ERR_REPT_SIZE; i++ ) + if ( ErrPats[i] ) + printf( "%s%d=%d ", i == ERR_REPT_SIZE? ">" : "", i, ErrPats[i] ); + printf( "\n" ); +} +int Patt_ManProfileErrorsOne( Vec_Wrd_t * vErrors, int nOuts ) +{ + Vec_Int_t * vCoErrs = Patt_ManOutputErrorCoverage( vErrors, nOuts ); + Vec_Int_t * vPatErrs = Patt_ManPatternErrorCoverage( vErrors, nOuts ); + Patt_ManProfileErrors( vCoErrs, vPatErrs ); + Vec_IntFree( vPatErrs ); + Vec_IntFree( vCoErrs ); + return 1; +} + +Vec_Int_t * Min_ManGetUnsolved( Gia_Man_t * p ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + int i, Driver; + Gia_ManForEachCoDriverId( p, Driver, i ) + if ( Driver > 0 ) + Vec_IntPush( vRes, i ); + return vRes; +} +Vec_Wrd_t * Min_ManCollect( Gia_Man_t * p, int nConf, int nConf2, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Vec_Int_t * vStats[3] = {0}; int i, iObj; + extern Gia_Man_t * Cec4_ManSimulateTest4( Gia_Man_t * p, int nBTLimit, int nBTLimitPo, int fVerbose ); + Gia_Man_t * pSwp = Cec4_ManSimulateTest4( p, nConf, nConf2, 0 ); + abctime clkSweep = Abc_Clock() - clk; + int nArgs = fVerbose ? printf( "Generating patterns: Conf = %d (%d). Tries = %d. Pats = %d. Sim = %d. SAT = %d.\n", + nConf, nConf2, nMaxTries, nMinCexes, fUseSim, fUseSat ) : 0; + Vec_Int_t * vOuts = Min_ManGetUnsolved( pSwp ); + Gia_Man_t * pSwp2 = Gia_ManDupSelectedOutputs( pSwp, vOuts ); + Vec_Wec_t * vCexes = Min_ManComputeCexes( pSwp2, NULL, nMaxTries, nMinCexes, vStats, fUseSim, fUseSat, fVerbose ); + Vec_Wrd_t * vSimsPi = Min_ManBitPack( p, vCexes, 1, nMinCexes, vStats[0], fVerbose ); + Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( pSwp2, vSimsPi, 1 ); + Vec_Int_t * vCounts = Patt_ManOutputErrorCoverage( vSimsPo, Vec_IntSize(vOuts) ); + if ( fVerbose ) + { + Patt_ManProfileErrorsOne( vSimsPo, Vec_IntSize(vOuts) ); + Abc_PrintTime( 1, "Sweep time", clkSweep ); + Abc_PrintTime( 1, "Total time", Abc_Clock() - clk ); + } + if ( 0 ) + { + printf( "Unsolved = %4d ", Vec_IntSize(vOuts) ); + Gia_ManPrintStats( pSwp2, NULL ); + Vec_IntForEachEntry( vOuts, iObj, i ) + { + printf( "%4d : ", i ); + printf( "Out = %5d ", iObj ); + printf( "SimAll =%8d ", Vec_IntEntry(vStats[0], i) ); + printf( "SimGood =%8d ", Vec_IntEntry(vStats[1], i) ); + printf( "PatsAll =%8d ", Vec_IntEntry(vStats[2], i) ); + printf( "Count = %5d ", Vec_IntEntry(vCounts, i) ); + printf( "\n" ); + if ( i == 20 ) + break; + } + } + for ( i = 0; i < 3; i++ ) + Vec_IntFree( vStats[i] ); + Vec_IntFree( vCounts ); + Vec_WrdFree( vSimsPo ); + Vec_WecFree( vCexes ); + Vec_IntFree( vOuts ); + Gia_ManStop( pSwp ); + Gia_ManStop( pSwp2 ); + nArgs = 0; + return vSimsPi; +} +void Min_ManTest2( Gia_Man_t * p ) +{ + Vec_Wrd_t * vSimsPi = Min_ManCollect( p, 100000, 100000, 10000, 20, 1, 1, 0 ); + Vec_WrdFreeP( &vSimsPi ); +} + + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index bfafdcfd..a9706742 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -2522,6 +2522,106 @@ int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int return RetValue; } +/**Function************************************************************* + + Synopsis [Serialization.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSim2ArrayOne( Vec_Wrd_t * vSimsPi, Vec_Int_t * vRes ) +{ + word * pInfo = Vec_WrdArray(vSimsPi); int w, i; + word * pCare = pInfo + Vec_WrdSize(vSimsPi); + Vec_IntClear( vRes ); + for ( w = 0; w < Vec_WrdSize(vSimsPi); w++ ) + if ( pCare[w] ) + for ( i = 0; i < 64; i++ ) + if ( Abc_TtGetBit(pCare, w*64+i) ) + Vec_IntPush( vRes, Abc_Var2Lit(w*64+i, Abc_TtGetBit(pInfo, w*64+i)) ); + Vec_IntPush( vRes, Vec_WrdSize(vSimsPi) ); +} +Vec_Wec_t * Gia_ManSim2Array( Vec_Ptr_t * vSims ) +{ + Vec_Wec_t * vRes = Vec_WecStart( Vec_PtrSize(vSims) ); + Vec_Int_t * vLevel; int i; + Vec_WecForEachLevel( vRes, vLevel, i ) + Gia_ManSim2ArrayOne( (Vec_Wrd_t *)Vec_PtrEntry(vSims, i), vLevel ); + return vRes; +} + +Vec_Wrd_t * Gia_ManArray2SimOne( Vec_Int_t * vRes ) +{ + int i, iLit, nWords = Vec_IntEntryLast(vRes); + Vec_Wrd_t * vSimsPi = Vec_WrdStart( 2*nWords ); + word * pInfo = Vec_WrdArray(vSimsPi); + word * pCare = pInfo + nWords; + Vec_IntPop( vRes ); + Vec_IntForEachEntry( vRes, iLit, i ) + { + Abc_TtXorBit( pCare, Abc_Lit2Var(iLit) ); + if ( Abc_LitIsCompl(iLit) ) + Abc_TtXorBit( pInfo, Abc_Lit2Var(iLit) ); + } + Vec_IntPush( vRes, nWords ); + Vec_WrdShrink( vSimsPi, Vec_WrdSize(vSimsPi)/2 ); + return vSimsPi; +} +Vec_Ptr_t * Gia_ManArray2Sim( Vec_Wec_t * vRes ) +{ + Vec_Ptr_t * vSims = Vec_PtrAlloc( Vec_WecSize(vRes) ); + Vec_Int_t * vLevel; int i; + Vec_WecForEachLevel( vRes, vLevel, i ) + Vec_PtrPush( vSims, Gia_ManArray2SimOne(vLevel) ); + return vSims; +} + +void Gia_ManSimArrayTest( Vec_Wrd_t * vSimsPi ) +{ + Vec_Ptr_t * vTemp = Vec_PtrAlloc( 2 ); + Vec_PtrPushTwo( vTemp, vSimsPi, vSimsPi ); + { + Vec_Wec_t * vRes = Gia_ManSim2Array( vTemp ); + Vec_WecDumpBin( "temp.sims", vRes, 1 ); + { + Vec_Wec_t * vRes = Vec_WecReadBin( "temp.sims", 1 ); + Vec_Ptr_t * vTemp2 = Gia_ManArray2Sim( vRes ); + Vec_Wrd_t * vSimsPi2 = (Vec_Wrd_t *)Vec_PtrEntry( vTemp2, 0 ); + Vec_Wrd_t * vSimsPi3 = (Vec_Wrd_t *)Vec_PtrEntry( vTemp2, 1 ); + + Abc_TtAnd( Vec_WrdArray(vSimsPi), Vec_WrdArray(vSimsPi), Vec_WrdArray(vSimsPi)+Vec_WrdSize(vSimsPi), Vec_WrdSize(vSimsPi), 0 ); + + vSimsPi->nSize *= 2; + vSimsPi2->nSize *= 2; + vSimsPi3->nSize *= 2; + Vec_WrdDumpHex( "test1.hex", vSimsPi, 1, 1 ); + Vec_WrdDumpHex( "test2.hex", vSimsPi2, 1, 1 ); + Vec_WrdDumpHex( "test3.hex", vSimsPi3, 1, 1 ); + vSimsPi->nSize /= 2; + vSimsPi2->nSize /= 2; + vSimsPi3->nSize /= 2; + + if ( Vec_WrdEqual( vSimsPi, vSimsPi2 ) ) + printf( "Success.\n" ); + else + printf( "Failure.\n" ); + if ( Vec_WrdEqual( vSimsPi, vSimsPi3 ) ) + printf( "Success.\n" ); + else + printf( "Failure.\n" ); + Vec_WrdFree( vSimsPi2 ); + Vec_WrdFree( vSimsPi3 ); + Vec_PtrFree( vTemp2 ); + Vec_WecFree( vRes ); + } + Vec_WecFree( vRes ); + } + Vec_PtrFree( vTemp ); +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 8cbcaa25..d801a243 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -60,6 +60,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaOf.c \ src/aig/gia/giaPack.c \ src/aig/gia/giaPat.c \ + src/aig/gia/giaPat2.c \ src/aig/gia/giaPf.c \ src/aig/gia/giaQbf.c \ src/aig/gia/giaReshape1.c \ -- cgit v1.2.3