| /**CFile**************************************************************** |
| |
| FileName [simSymSat.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Network and node package.] |
| |
| Synopsis [Satisfiability to determine two variable symmetries.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: simSymSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "base/abc/abc.h" |
| #include "proof/fraig/fraig.h" |
| #include "sim.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| static int Sim_SymmsSatProveOne( Sym_Man_t * p, int Out, int Var1, int Var2, unsigned * pPattern ); |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Tries to prove the remaining pairs using SAT.] |
| |
| Description [Continues to prove as long as it encounters symmetric pairs. |
| Returns 1 if a non-symmetric pair is found (which gives a counter-example). |
| Returns 0 if it finishes considering all pairs for all outputs.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Sim_SymmsGetPatternUsingSat( Sym_Man_t * p, unsigned * pPattern ) |
| { |
| Vec_Int_t * vSupport; |
| Extra_BitMat_t * pMatSym, * pMatNonSym; |
| int Index1, Index2, Index3, IndexU, IndexV; |
| int v, u, i, k, b, out; |
| |
| // iterate through outputs |
| for ( out = p->iOutput; out < p->nOutputs; out++ ) |
| { |
| pMatSym = (Extra_BitMat_t *)Vec_PtrEntry( p->vMatrSymms, out ); |
| pMatNonSym = (Extra_BitMat_t *)Vec_PtrEntry( p->vMatrNonSymms, out ); |
| |
| // go through the remaining variable pairs |
| vSupport = Vec_VecEntryInt( p->vSupports, out ); |
| Vec_IntForEachEntry( vSupport, v, Index1 ) |
| Vec_IntForEachEntryStart( vSupport, u, Index2, Index1+1 ) |
| { |
| if ( Extra_BitMatrixLookup1( pMatSym, v, u ) || Extra_BitMatrixLookup1( pMatNonSym, v, u ) ) |
| continue; |
| p->nSatRuns++; |
| |
| // collect the support variables that are symmetric with u and v |
| Vec_IntClear( p->vVarsU ); |
| Vec_IntClear( p->vVarsV ); |
| Vec_IntForEachEntry( vSupport, b, Index3 ) |
| { |
| if ( Extra_BitMatrixLookup1( pMatSym, u, b ) ) |
| Vec_IntPush( p->vVarsU, b ); |
| if ( Extra_BitMatrixLookup1( pMatSym, v, b ) ) |
| Vec_IntPush( p->vVarsV, b ); |
| } |
| |
| if ( Sim_SymmsSatProveOne( p, out, v, u, pPattern ) ) |
| { // update the symmetric variable info |
| p->nSatRunsUnsat++; |
| Vec_IntForEachEntry( p->vVarsU, i, IndexU ) |
| Vec_IntForEachEntry( p->vVarsV, k, IndexV ) |
| { |
| Extra_BitMatrixInsert1( pMatSym, i, k ); // Theorem 1 |
| Extra_BitMatrixInsert2( pMatSym, i, k ); // Theorem 1 |
| Extra_BitMatrixOrTwo( pMatNonSym, i, k ); // Theorem 2 |
| } |
| } |
| else |
| { // update the assymmetric variable info |
| p->nSatRunsSat++; |
| Vec_IntForEachEntry( p->vVarsU, i, IndexU ) |
| Vec_IntForEachEntry( p->vVarsV, k, IndexV ) |
| { |
| Extra_BitMatrixInsert1( pMatNonSym, i, k ); // Theorem 3 |
| Extra_BitMatrixInsert2( pMatNonSym, i, k ); // Theorem 3 |
| } |
| |
| // remember the out |
| p->iOutput = out; |
| p->iVar1Old = p->iVar1; |
| p->iVar2Old = p->iVar2; |
| p->iVar1 = v; |
| p->iVar2 = u; |
| return 1; |
| |
| } |
| } |
| // make sure that the symmetry matrix contains only cliques |
| assert( Extra_BitMatrixIsClique( pMatSym ) ); |
| } |
| |
| // mark that we finished all outputs |
| p->iOutput = p->nOutputs; |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns 1 if the variables are symmetric; 0 otherwise.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Sim_SymmsSatProveOne( Sym_Man_t * p, int Out, int Var1, int Var2, unsigned * pPattern ) |
| { |
| Fraig_Params_t Params; |
| Fraig_Man_t * pMan; |
| Abc_Ntk_t * pMiter; |
| int RetValue, i; |
| abctime clk; |
| int * pModel; |
| |
| // get the miter for this problem |
| pMiter = Abc_NtkMiterForCofactors( p->pNtk, Out, Var1, Var2 ); |
| // transform the miter into a fraig |
| Fraig_ParamsSetDefault( &Params ); |
| Params.fInternal = 1; |
| Params.nPatsRand = 512; |
| Params.nPatsDyna = 512; |
| Params.nSeconds = ABC_INFINITY; |
| |
| clk = Abc_Clock(); |
| pMan = (Fraig_Man_t *)Abc_NtkToFraig( pMiter, &Params, 0, 0 ); |
| p->timeFraig += Abc_Clock() - clk; |
| clk = Abc_Clock(); |
| Fraig_ManProveMiter( pMan ); |
| p->timeSat += Abc_Clock() - clk; |
| |
| // analyze the result |
| RetValue = Fraig_ManCheckMiter( pMan ); |
| // assert( RetValue >= 0 ); |
| // save the pattern |
| if ( RetValue == 0 ) |
| { |
| // get the pattern |
| pModel = Fraig_ManReadModel( pMan ); |
| assert( pModel != NULL ); |
| //printf( "Disproved by SAT: out = %d pair = (%d, %d)\n", Out, Var1, Var2 ); |
| // transfer the model into the pattern |
| for ( i = 0; i < p->nSimWords; i++ ) |
| pPattern[i] = 0; |
| for ( i = 0; i < p->nInputs; i++ ) |
| if ( pModel[i] ) |
| Sim_SetBit( pPattern, i ); |
| // make sure these variables have the same value (1) |
| Sim_SetBit( pPattern, Var1 ); |
| Sim_SetBit( pPattern, Var2 ); |
| } |
| else if ( RetValue == -1 ) |
| { |
| // this should never happen; if it happens, such is life |
| // we are conservative and assume that there is no symmetry |
| //printf( "STRANGE THING: out = %d %s pair = (%d %s, %d %s)\n", |
| // Out, Abc_ObjName(Abc_NtkCo(p->pNtk,Out)), |
| // Var1, Abc_ObjName(Abc_NtkCi(p->pNtk,Var1)), |
| // Var2, Abc_ObjName(Abc_NtkCi(p->pNtk,Var2)) ); |
| memset( pPattern, 0, sizeof(unsigned) * p->nSimWords ); |
| RetValue = 0; |
| } |
| // delete the fraig manager |
| Fraig_ManFree( pMan ); |
| // delete the miter |
| Abc_NtkDelete( pMiter ); |
| return RetValue; |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |