diff options
Diffstat (limited to 'src/aig/fra')
-rw-r--r-- | src/aig/fra/fra.h | 16 | ||||
-rw-r--r-- | src/aig/fra/fraClaus.c | 37 | ||||
-rw-r--r-- | src/aig/fra/fraCore.c | 1 | ||||
-rw-r--r-- | src/aig/fra/fraHot.c | 424 | ||||
-rw-r--r-- | src/aig/fra/fraInd.c | 43 | ||||
-rw-r--r-- | src/aig/fra/fraIndVer.c | 161 | ||||
-rw-r--r-- | src/aig/fra/fraMan.c | 4 | ||||
-rw-r--r-- | src/aig/fra/fraSat.c | 107 | ||||
-rw-r--r-- | src/aig/fra/fraSec.c | 6 | ||||
-rw-r--r-- | src/aig/fra/fraSim.c | 2 | ||||
-rw-r--r-- | src/aig/fra/module.make | 2 |
11 files changed, 780 insertions, 23 deletions
diff --git a/src/aig/fra/fra.h b/src/aig/fra/fra.h index 8d7116c7..339fd810 100644 --- a/src/aig/fra/fra.h +++ b/src/aig/fra/fra.h @@ -80,6 +80,7 @@ struct Fra_Par_t_ int fRewrite; // use rewriting for constraint reduction int fLatchCorr; // computes latch correspondence only int fUseImps; // use implications + int fUse1Hot; // use one-hotness conditions int fWriteImps; // record implications int fDontShowBar; // does not show progressbar during fraiging }; @@ -153,6 +154,8 @@ struct Fra_Man_t_ int nPatWords; // the number of words in the counter example unsigned * pPatWords; // the counter example Vec_Int_t * vCex; + // one-hotness conditions + Vec_Int_t * vOneHots; // satisfiability solving sat_solver * pSat; // SAT solver int nSatVars; // the number of variables currently used @@ -265,6 +268,14 @@ extern int Fra_FraigMiterAssertedOutput( Aig_Man_t * p ); extern Aig_Man_t * Fra_FraigPerform( Aig_Man_t * pManAig, Fra_Par_t * pPars ); extern Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig, int nConfMax ); extern Aig_Man_t * Fra_FraigEquivence( Aig_Man_t * pManAig, int nConfMax, int fProve ); +/*=== fraHot.c ========================================================*/ +extern Vec_Int_t * Fra_OneHotCompute( Fra_Man_t * p, Fra_Sml_t * pSim ); +extern void Fra_OneHotAssume( Fra_Man_t * p, Vec_Int_t * vOneHots ); +extern void Fra_OneHotCheck( Fra_Man_t * p, Vec_Int_t * vOneHots ); +extern int Fra_OneHotRefineUsingCex( Fra_Man_t * p, Vec_Int_t * vOneHots ); +extern int Fra_OneHotCount( Fra_Man_t * p, Vec_Int_t * vOneHots ); +extern void Fra_OneHotEstimateCoverage( Fra_Man_t * p, Vec_Int_t * vOneHots ); +extern Aig_Man_t * Fra_OneHotCreateExdc( Fra_Man_t * p, Vec_Int_t * vOneHots ); /*=== fraImp.c ========================================================*/ extern Vec_Int_t * Fra_ImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit, int fLatchCorr ); extern void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps, int * pSatVarNums ); @@ -275,7 +286,9 @@ extern double Fra_ImpComputeStateSpaceRatio( Fra_Man_t * p ); extern int Fra_ImpVerifyUsingSimulation( Fra_Man_t * p ); extern void Fra_ImpRecordInManager( Fra_Man_t * p, Aig_Man_t * pNew ); /*=== fraInd.c ========================================================*/ -extern Aig_Man_t * Fra_FraigInduction( Aig_Man_t * p, int nFramesP, int nFramesK, int nMaxImps, int nMaxLevs, int fRewrite, int fUseImps, int fLatchCorr, int fWriteImps, int fVerbose, int * pnIter ); +extern Aig_Man_t * Fra_FraigInduction( Aig_Man_t * p, int nFramesP, int nFramesK, int nMaxImps, int nMaxLevs, int fRewrite, int fUseImps, int fLatchCorr, int fWriteImps, int fUse1Hot, int fVerbose, int * pnIter ); +/*=== fraIndVer.c =====================================================*/ +extern int Fra_InvariantVerify( Aig_Man_t * p, int nFrames, Vec_Int_t * vClauses, Vec_Int_t * vLits ); /*=== fraLcr.c ========================================================*/ extern Aig_Man_t * Fra_FraigLatchCorrespondence( Aig_Man_t * pAig, int nFramesP, int nConfMax, int fProve, int fVerbose, int * pnIter ); /*=== fraMan.c ========================================================*/ @@ -290,6 +303,7 @@ extern void Fra_ManPrint( Fra_Man_t * p ); /*=== fraSat.c ========================================================*/ extern int Fra_NodesAreEquiv( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ); extern int Fra_NodesAreImp( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew, int fComplL, int fComplR ); +extern int Fra_NodesAreClause( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew, int fComplL, int fComplR ); extern int Fra_NodeIsConst( Fra_Man_t * p, Aig_Obj_t * pNew ); /*=== fraSec.c ========================================================*/ extern int Fra_FraigSec( Aig_Man_t * p, int nFrames, int fRetimeFirst, int fVerbose, int fVeryVerbose ); diff --git a/src/aig/fra/fraClaus.c b/src/aig/fra/fraClaus.c index e5b8a126..7929b25d 100644 --- a/src/aig/fra/fraClaus.c +++ b/src/aig/fra/fraClaus.c @@ -67,7 +67,6 @@ struct Clu_Man_t_ // clauses proven Vec_Int_t * vLitsProven; Vec_Int_t * vClausesProven; - int nClausesProven; // counter-examples Vec_Ptr_t * vCexes; int nCexes; @@ -516,6 +515,21 @@ int Fra_ClausCollectLatchClauses( Clu_Man_t * p, Fra_Sml_t * pSeq ) nCountConst = nCountImps = 0; CostMax = p->nSimWords * 32; + + // add the property + { + Aig_Obj_t * pObj; + int Lits[1]; + pObj = Aig_ManPo( p->pAig, 0 ); + Lits[0] = toLitCond( p->pCnf->pVarNums[pObj->Id], 1 ); + Vec_IntPush( p->vLits, Lits[0] ); + Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) ); + Vec_IntPush( p->vCosts, CostMax ); + nCountConst++; +// printf( "Added the target property to the set of clauses to be inductively checked.\n" ); + } + + pSeq->nWordsPref = p->nSimWordsPref; Aig_ManForEachLoSeq( p->pAig, pObj1, i ) { @@ -1600,11 +1614,11 @@ if ( p->fVerbose ) clk = clock(); // derive CNF - if ( p->fTarget ) - p->pAig->nRegs++; +// if ( p->fTarget ) +// p->pAig->nRegs++; p->pCnf = Cnf_DeriveSimple( p->pAig, Aig_ManPoNum(p->pAig) ); - if ( p->fTarget ) - p->pAig->nRegs--; +// if ( p->fTarget ) +// p->pAig->nRegs--; if ( fVerbose ) { //PRT( "CNF ", clock() - clk ); @@ -1705,6 +1719,9 @@ clk = clock(); } clk = clock(); } + // add proved clauses to storage + Fra_ClausAddToStorage( p ); + // report the results if ( p->fTarget ) { if ( Counter == -1 ) @@ -1722,12 +1739,14 @@ clk = clock(); printf( "Finished proving inductive clauses. " ); PRT( "Time ", clock() - clkTotal ); } - - // add proved clauses to storage - Fra_ClausAddToStorage( p ); } - if ( !p->fTarget && p->fVerbose ) + // verify the computed interpolant + Fra_InvariantVerify( pAig, nFrames, p->vClausesProven, p->vLitsProven ); +// printf( "THIS COMMAND IS KNOWN TO HAVE A BUG!\n" ); + +// if ( !p->fTarget && p->fVerbose ) + if ( p->fVerbose ) { Fra_ClausPrintIndClauses( p ); Fra_ClausEstimateCoverage( p ); diff --git a/src/aig/fra/fraCore.c b/src/aig/fra/fraCore.c index 95d65e25..0157421b 100644 --- a/src/aig/fra/fraCore.c +++ b/src/aig/fra/fraCore.c @@ -378,6 +378,7 @@ clk = clock(); // call back the procedure to check implications if ( pManAig->pImpFunc ) pManAig->pImpFunc( p, pManAig->pImpData ); + // no need to filter one-hot clauses because they satisfy base case by construction // finalize the fraiged manager Fra_ManFinalizeComb( p ); if ( p->pPars->fChoicing ) diff --git a/src/aig/fra/fraHot.c b/src/aig/fra/fraHot.c new file mode 100644 index 00000000..6783b459 --- /dev/null +++ b/src/aig/fra/fraHot.c @@ -0,0 +1,424 @@ +/**CFile**************************************************************** + + FileName [fraHot.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [New FRAIG package.] + + Synopsis [Computing and using one-hotness conditions.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 30, 2007.] + + Revision [$Id: fraHot.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fra.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline int Fra_RegToLit( int n, int c ) { return c? -n-1 : n+1; } +static inline int Fra_LitReg( int n ) { return (n>0)? n-1 : -n-1; } +static inline int Fra_LitSign( int n ) { return (n<0); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Returns 1 if simulation info is composed of all zeros.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_OneHotNodeIsConst( Fra_Sml_t * pSeq, Aig_Obj_t * pObj ) +{ + unsigned * pSims; + int i; + pSims = Fra_ObjSim(pSeq, pObj->Id); + for ( i = pSeq->nWordsPref; i < pSeq->nWordsTotal; i++ ) + if ( pSims[i] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if simulation infos are equal.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_OneHotNodesAreEqual( Fra_Sml_t * pSeq, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) +{ + unsigned * pSims0, * pSims1; + int i; + pSims0 = Fra_ObjSim(pSeq, pObj0->Id); + pSims1 = Fra_ObjSim(pSeq, pObj1->Id); + for ( i = pSeq->nWordsPref; i < pSeq->nWordsTotal; i++ ) + if ( pSims0[i] != pSims1[i] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if implications holds.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_OneHotNodesAreClause( Fra_Sml_t * pSeq, Aig_Obj_t * pObj1, Aig_Obj_t * pObj2, int fCompl1, int fCompl2 ) +{ + unsigned * pSim1, * pSim2; + int k; + pSim1 = Fra_ObjSim(pSeq, pObj1->Id); + pSim2 = Fra_ObjSim(pSeq, pObj2->Id); + if ( fCompl1 && fCompl2 ) + { + for ( k = pSeq->nWordsPref; k < pSeq->nWordsTotal; k++ ) + if ( pSim1[k] & pSim2[k] ) + return 0; + } + else if ( fCompl1 ) + { + for ( k = pSeq->nWordsPref; k < pSeq->nWordsTotal; k++ ) + if ( pSim1[k] & ~pSim2[k] ) + return 0; + } + else if ( fCompl2 ) + { + for ( k = pSeq->nWordsPref; k < pSeq->nWordsTotal; k++ ) + if ( ~pSim1[k] & pSim2[k] ) + return 0; + } + else + assert( 0 ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Computes one-hot implications.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Fra_OneHotCompute( Fra_Man_t * p, Fra_Sml_t * pSim ) +{ + int fSkipConstEqu = 1; + Vec_Int_t * vOneHots; + Aig_Obj_t * pObj1, * pObj2; + int i, k; + int nTruePis = Aig_ManPiNum(pSim->pAig) - Aig_ManRegNum(pSim->pAig); + assert( pSim->pAig == p->pManAig ); + vOneHots = Vec_IntAlloc( 100 ); + Aig_ManForEachLoSeq( pSim->pAig, pObj1, i ) + { + if ( fSkipConstEqu && Fra_OneHotNodeIsConst(pSim, pObj1) ) + continue; + assert( i-nTruePis >= 0 ); +// Aig_ManForEachLoSeq( pSim->pAig, pObj2, k ) +// Vec_PtrForEachEntryStart( pSim->pAig->vPis, pObj2, k, Aig_ManPiNum(p)-Aig_ManRegNum(p) ) + Vec_PtrForEachEntryStart( pSim->pAig->vPis, pObj2, k, i+1 ) + { + if ( fSkipConstEqu && Fra_OneHotNodeIsConst(pSim, pObj2) ) + continue; + if ( fSkipConstEqu && Fra_OneHotNodesAreEqual( pSim, pObj1, pObj2 ) ) + continue; + assert( k-nTruePis >= 0 ); + if ( Fra_OneHotNodesAreClause( pSim, pObj1, pObj2, 1, 1 ) ) + { + Vec_IntPush( vOneHots, Fra_RegToLit(i-nTruePis, 1) ); + Vec_IntPush( vOneHots, Fra_RegToLit(k-nTruePis, 1) ); + continue; + } + if ( Fra_OneHotNodesAreClause( pSim, pObj1, pObj2, 0, 1 ) ) + { + Vec_IntPush( vOneHots, Fra_RegToLit(i-nTruePis, 0) ); + Vec_IntPush( vOneHots, Fra_RegToLit(k-nTruePis, 1) ); + continue; + } + if ( Fra_OneHotNodesAreClause( pSim, pObj1, pObj2, 1, 0 ) ) + { + Vec_IntPush( vOneHots, Fra_RegToLit(i-nTruePis, 1) ); + Vec_IntPush( vOneHots, Fra_RegToLit(k-nTruePis, 0) ); + continue; + } + } + } + return vOneHots; +} + +/**Function************************************************************* + + Synopsis [Assumes one-hot implications in the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +**********************************************************************/ +void Fra_OneHotAssume( Fra_Man_t * p, Vec_Int_t * vOneHots ) +{ + Aig_Obj_t * pObj1, * pObj2; + int i, Out1, Out2, pLits[2]; + int nPiNum = Aig_ManPiNum(p->pManFraig) - Aig_ManRegNum(p->pManFraig); + assert( p->pPars->nFramesK == 1 ); // add to only one frame + for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 ) + { + Out1 = Vec_IntEntry( vOneHots, i ); + Out2 = Vec_IntEntry( vOneHots, i+1 ); + if ( Out1 == 0 && Out2 == 0 ) + continue; + pObj1 = Aig_ManPi( p->pManFraig, nPiNum + Fra_LitReg(Out1) ); + pObj2 = Aig_ManPi( p->pManFraig, nPiNum + Fra_LitReg(Out2) ); + pLits[0] = toLitCond( Fra_ObjSatNum(pObj1), Fra_LitSign(Out1) ); + pLits[1] = toLitCond( Fra_ObjSatNum(pObj2), Fra_LitSign(Out2) ); + // add contraint to solver + if ( !sat_solver_addclause( p->pSat, pLits, pLits + 2 ) ) + { + printf( "Fra_OneHotAssume(): Adding clause makes SAT solver unsat.\n" ); + sat_solver_delete( p->pSat ); + p->pSat = NULL; + return; + } + } +} + +/**Function************************************************************* + + Synopsis [Checks one-hot implications.] + + Description [] + + SideEffects [] + + SeeAlso [] + +**********************************************************************/ +void Fra_OneHotCheck( Fra_Man_t * p, Vec_Int_t * vOneHots ) +{ + Aig_Obj_t * pObj1, * pObj2; + int RetValue, i, Out1, Out2; + int nTruePos = Aig_ManPoNum(p->pManFraig) - Aig_ManRegNum(p->pManFraig); + for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 ) + { + Out1 = Vec_IntEntry( vOneHots, i ); + Out2 = Vec_IntEntry( vOneHots, i+1 ); + if ( Out1 == 0 && Out2 == 0 ) + continue; + pObj1 = Aig_ManPo( p->pManFraig, nTruePos + Fra_LitReg(Out1) ); + pObj2 = Aig_ManPo( p->pManFraig, nTruePos + Fra_LitReg(Out2) ); + RetValue = Fra_NodesAreClause( p, pObj1, pObj2, Fra_LitSign(Out1), Fra_LitSign(Out2) ); + if ( RetValue != 1 ) + { + p->pCla->fRefinement = 1; + if ( RetValue == 0 ) + Fra_SmlResimulate( p ); + if ( Vec_IntEntry(vOneHots, i) != 0 ) + printf( "Fra_OneHotCheck(): Clause is not refined!\n" ); + assert( Vec_IntEntry(vOneHots, i) == 0 ); + } + } +} + +/**Function************************************************************* + + Synopsis [Removes those implications that no longer hold.] + + Description [Returns 1 if refinement has happened.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_OneHotRefineUsingCex( Fra_Man_t * p, Vec_Int_t * vOneHots ) +{ + Aig_Obj_t * pObj1, * pObj2; + int i, Out1, Out2, RetValue = 0; + int nPiNum = Aig_ManPiNum(p->pManAig) - Aig_ManRegNum(p->pManAig); + assert( p->pSml->pAig == p->pManAig ); + for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 ) + { + Out1 = Vec_IntEntry( vOneHots, i ); + Out2 = Vec_IntEntry( vOneHots, i+1 ); + if ( Out1 == 0 && Out2 == 0 ) + continue; + // get the corresponding nodes + pObj1 = Aig_ManPi( p->pManAig, nPiNum + Fra_LitReg(Out1) ); + pObj2 = Aig_ManPi( p->pManAig, nPiNum + Fra_LitReg(Out2) ); + // check if implication holds using this simulation info + if ( !Fra_OneHotNodesAreClause( p->pSml, pObj1, pObj2, Fra_LitSign(Out1), Fra_LitSign(Out2) ) ) + { + Vec_IntWriteEntry( vOneHots, i, 0 ); + Vec_IntWriteEntry( vOneHots, i+1, 0 ); + RetValue = 1; + } + } + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Removes those implications that no longer hold.] + + Description [Returns 1 if refinement has happened.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_OneHotCount( Fra_Man_t * p, Vec_Int_t * vOneHots ) +{ + int i, Out1, Out2, Counter = 0; + for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 ) + { + Out1 = Vec_IntEntry( vOneHots, i ); + Out2 = Vec_IntEntry( vOneHots, i+1 ); + if ( Out1 == 0 && Out2 == 0 ) + continue; + Counter++; + } + return Counter; +} + +/**Function************************************************************* + + Synopsis [Estimates the coverage of state space by clauses.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fra_OneHotEstimateCoverage( Fra_Man_t * p, Vec_Int_t * vOneHots ) +{ + int nSimWords = (1<<14); + int nRegs = Aig_ManRegNum(p->pManAig); + Vec_Ptr_t * vSimInfo; + unsigned * pSim1, * pSim2, * pSimTot; + int i, w, Out1, Out2, nCovered, Counter = 0; + int clk = clock(); + + // generate random sim-info at register outputs + vSimInfo = Vec_PtrAllocSimInfo( nRegs + 1, nSimWords ); + srand( 0xAABBAABB ); + for ( i = 0; i < nRegs; i++ ) + { + pSim1 = Vec_PtrEntry( vSimInfo, i ); + for ( w = 0; w < nSimWords; w++ ) + pSim1[w] = Fra_ObjRandomSim(); + } + pSimTot = Vec_PtrEntry( vSimInfo, nRegs ); + + // collect simulation info + memset( pSimTot, 0, sizeof(unsigned) * nSimWords ); + for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 ) + { + Out1 = Vec_IntEntry( vOneHots, i ); + Out2 = Vec_IntEntry( vOneHots, i+1 ); + if ( Out1 == 0 && Out2 == 0 ) + continue; +//printf( "(%c%d,%c%d) ", +//Fra_LitSign(Out1)? '-': '+', Fra_LitReg(Out1), +//Fra_LitSign(Out2)? '-': '+', Fra_LitReg(Out2) ); + Counter++; + pSim1 = Vec_PtrEntry( vSimInfo, Fra_LitReg(Out1) ); + pSim2 = Vec_PtrEntry( vSimInfo, Fra_LitReg(Out2) ); + if ( Fra_LitSign(Out1) && Fra_LitSign(Out2) ) + for ( w = 0; w < nSimWords; w++ ) + pSimTot[w] |= pSim1[w] & pSim2[w]; + else if ( Fra_LitSign(Out1) ) + for ( w = 0; w < nSimWords; w++ ) + pSimTot[w] |= pSim1[w] & ~pSim2[w]; + else if ( Fra_LitSign(Out2) ) + for ( w = 0; w < nSimWords; w++ ) + pSimTot[w] |= ~pSim1[w] & pSim2[w]; + else + assert( 0 ); + } +//printf( "\n" ); + // count the total number of patterns contained in the don't-care + nCovered = 0; + for ( w = 0; w < nSimWords; w++ ) + nCovered += Aig_WordCountOnes( pSimTot[w] ); + Vec_PtrFree( vSimInfo ); + // print the result + printf( "Care states ratio = %f. ", 1.0 * (nSimWords * 32 - nCovered) / (nSimWords * 32) ); + printf( "(%d out of %d patterns) ", nSimWords * 32 - nCovered, nSimWords * 32 ); + PRT( "Time", clock() - clk ); +} + +/**Function************************************************************* + + Synopsis [Creates one-hotness EXDC.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Fra_OneHotCreateExdc( Fra_Man_t * p, Vec_Int_t * vOneHots ) +{ + Aig_Man_t * pNew; + Aig_Obj_t * pObj1, * pObj2, * pObj; + int i, Out1, Out2; + pNew = Aig_ManStart( Vec_IntSize(vOneHots)/2 ); + for ( i = 0; i < Aig_ManRegNum(p->pManAig); i++ ) + Aig_ObjCreatePi(pNew); + for ( i = 0; i < Vec_IntSize(vOneHots); i += 2 ) + { + Out1 = Vec_IntEntry( vOneHots, i ); + Out2 = Vec_IntEntry( vOneHots, i+1 ); + if ( Out1 == 0 && Out2 == 0 ) + continue; + pObj1 = Aig_ManPi( pNew, Fra_LitReg(Out1) ); + pObj2 = Aig_ManPi( pNew, Fra_LitReg(Out2) ); + pObj1 = Aig_NotCond( pObj1, Fra_LitSign(Out1) ); + pObj2 = Aig_NotCond( pObj2, Fra_LitSign(Out2) ); + pObj = Aig_Or( pNew, pObj1, pObj2 ); + Aig_ObjCreatePo( pNew, pObj ); + } + Aig_ManCleanup(pNew); + printf( "Created AIG with %d nodes and %d outputs.\n", Aig_ManNodeNum(pNew), Aig_ManPoNum(pNew) ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/fra/fraInd.c b/src/aig/fra/fraInd.c index 1c2140bb..f345b6d1 100644 --- a/src/aig/fra/fraInd.c +++ b/src/aig/fra/fraInd.c @@ -243,7 +243,7 @@ void Fra_FramesAddMore( Aig_Man_t * p, int nFrames ) SeeAlso [] ***********************************************************************/ -Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK, int nMaxImps, int nMaxLevs, int fRewrite, int fUseImps, int fLatchCorr, int fWriteImps, int fVerbose, int * pnIter ) +Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK, int nMaxImps, int nMaxLevs, int fRewrite, int fUseImps, int fLatchCorr, int fWriteImps, int fUse1Hot, int fVerbose, int * pnIter ) { int fUseSimpleCnf = 0; int fUseOldSimulation = 0; @@ -288,6 +288,10 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK, pPars->fLatchCorr = fLatchCorr; pPars->fUseImps = fUseImps; pPars->fWriteImps = fWriteImps; + pPars->fUse1Hot = fUse1Hot; + + assert( !(pPars->nFramesP > 0 && pPars->fUse1Hot) ); + assert( !(pPars->nFramesK > 1 && pPars->fUse1Hot) ); // start the fraig manager for this run p = Fra_ManStart( pManAig, pPars ); @@ -316,6 +320,9 @@ PRT( "Time", clock() - clk ); } Fra_ClassesPrepare( p->pCla, p->pPars->fLatchCorr, p->pPars->nMaxLevs ); // Fra_ClassesPostprocess( p->pCla ); + // compute one-hotness conditions + if ( p->pPars->fUse1Hot ) + p->vOneHots = Fra_OneHotCompute( p, p->pSml ); // allocate new simulation manager for simulating counter-examples Fra_SmlStop( p->pSml ); p->pSml = Fra_SmlStart( pManAig, 0, pPars->nFramesK + 1, pPars->nSimWords ); @@ -347,6 +354,7 @@ PRT( "Time", clock() - clk ); { int nLitsOld = Fra_ClassesCountLits(p->pCla); int nImpsOld = p->pCla->vImps? Vec_IntSize(p->pCla->vImps) : 0; + int nHotsOld = p->vOneHots? Fra_OneHotCount(p, p->vOneHots) : 0; // mark the classes as non-refined p->pCla->fRefinement = 0; // derive non-init K-timeframes while implementing e-classes @@ -377,7 +385,7 @@ p->timeTrav += clock() - clk2; if ( p->pSat == NULL ) printf( "Fra_FraigInduction(): Adding implicationsn to CNF led to a conflict.\n" ); } - + // set the pointers to the manager Aig_ManForEachObj( p->pManFraig, pObj, i ) pObj->pData = p; @@ -395,6 +403,10 @@ p->timeTrav += clock() - clk2; } Cnf_DataFree( pCnf ); + // add one-hotness clauses + if ( p->pPars->fUse1Hot ) + Fra_OneHotAssume( p, p->vOneHots ); + // report the intermediate results if ( fVerbose ) { @@ -403,6 +415,8 @@ p->timeTrav += clock() - clk2; Fra_ClassesCountLits(p->pCla), p->pManFraig->nAsserts ); if ( p->pCla->vImps ) printf( "I = %6d. ", Vec_IntSize(p->pCla->vImps) ); + if ( p->pPars->fUse1Hot ) + printf( "1h = %6d. ", Fra_OneHotCount(p, p->vOneHots) ); printf( "NR = %6d. ", Aig_ManNodeNum(p->pManFraig) ); printf( "\n" ); } @@ -411,6 +425,8 @@ p->timeTrav += clock() - clk2; p->nSatCallsRecent = 0; p->nSatCallsSkipped = 0; clk2 = clock(); + if ( p->pPars->fUse1Hot ) + Fra_OneHotCheck( p, p->vOneHots ); Fra_FraigSweep( p ); if ( fVerbose ) { @@ -430,7 +446,8 @@ clk2 = clock(); // p->pCla->fRefinement = (int)(nLitsOld != Fra_ClassesCountLits(p->pCla)); if ( p->pCla->fRefinement && nLitsOld == Fra_ClassesCountLits(p->pCla) && - nImpsOld == (p->pCla->vImps? Vec_IntSize(p->pCla->vImps) : 0) ) + nImpsOld == (p->pCla->vImps? Vec_IntSize(p->pCla->vImps) : 0) && + nHotsOld == (p->vOneHots? Fra_OneHotCount(p, p->vOneHots) : 0) ) { printf( "Fra_FraigInduction(): Internal error. The result may not verify.\n" ); break; @@ -451,13 +468,21 @@ clk2 = clock(); // move the classes into representatives and reduce AIG clk2 = clock(); -// Fra_ClassesPrint( p->pCla, 1 ); - Fra_ClassesSelectRepr( p->pCla ); - Fra_ClassesCopyReprs( p->pCla, p->vTimeouts ); - pManAigNew = Aig_ManDupRepr( pManAig, 0 ); + if ( p->pPars->fWriteImps && p->vOneHots && Fra_OneHotCount(p, p->vOneHots) ) + { + pManAigNew = Aig_ManDup( pManAig, 1 ); + pManAigNew->pManExdc = Fra_OneHotCreateExdc( p, p->vOneHots ); + } + else + { + // Fra_ClassesPrint( p->pCla, 1 ); + Fra_ClassesSelectRepr( p->pCla ); + Fra_ClassesCopyReprs( p->pCla, p->vTimeouts ); + pManAigNew = Aig_ManDupRepr( pManAig, 0 ); + } // add implications to the manager - if ( fWriteImps && p->pCla->vImps && Vec_IntSize(p->pCla->vImps) ) - Fra_ImpRecordInManager( p, pManAigNew ); +// if ( fWriteImps && p->pCla->vImps && Vec_IntSize(p->pCla->vImps) ) +// Fra_ImpRecordInManager( p, pManAigNew ); // cleanup the new manager Aig_ManSeqCleanup( pManAigNew ); // Aig_ManCountMergeRegs( pManAigNew ); diff --git a/src/aig/fra/fraIndVer.c b/src/aig/fra/fraIndVer.c new file mode 100644 index 00000000..efc516c9 --- /dev/null +++ b/src/aig/fra/fraIndVer.c @@ -0,0 +1,161 @@ +/**CFile**************************************************************** + + FileName [fraIndVer.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [New FRAIG package.] + + Synopsis [Verification of the inductive invariant.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 30, 2007.] + + Revision [$Id: fraIndVer.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fra.h" +#include "cnf.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Verifies the inductive invariant.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_InvariantVerify( Aig_Man_t * pAig, int nFrames, Vec_Int_t * vClauses, Vec_Int_t * vLits ) +{ + Cnf_Dat_t * pCnf; + sat_solver * pSat; + int * pStart; + int RetValue, Beg, End, i, k; + int CounterBase = 0, CounterInd = 0; + int clk = clock(); + + if ( nFrames != 1 ) + { + printf( "Invariant verification: Can only verify for K = 1\n" ); + return 1; + } + + // derive CNF + pCnf = Cnf_DeriveSimple( pAig, Aig_ManPoNum(pAig) ); +/* + // add the property + { + Aig_Obj_t * pObj; + int Lits[1]; + + pObj = Aig_ManPo( pAig, 0 ); + Lits[0] = toLitCond( pCnf->pVarNums[pObj->Id], 1 ); + + Vec_IntPush( vLits, Lits[0] ); + Vec_IntPush( vClauses, Vec_IntSize(vLits) ); + printf( "Added the target property to the set of clauses to be inductively checked.\n" ); + } +*/ + // derive initialized frames for the base case + pSat = Cnf_DataWriteIntoSolver( pCnf, nFrames, 1 ); + // check clauses in the base case + Beg = 0; + pStart = Vec_IntArray( vLits ); + Vec_IntForEachEntry( vClauses, End, i ) + { + // complement the literals + for ( k = Beg; k < End; k++ ) + pStart[k] = lit_neg(pStart[k]); + RetValue = sat_solver_solve( pSat, pStart + Beg, pStart + End, 0, 0, 0, 0 ); + for ( k = Beg; k < End; k++ ) + pStart[k] = lit_neg(pStart[k]); + Beg = End; + if ( RetValue == l_False ) + continue; +// printf( "Clause %d failed the base case.\n", i ); + CounterBase++; + } + sat_solver_delete( pSat ); + + // derive initialized frames for the base case + pSat = Cnf_DataWriteIntoSolver( pCnf, nFrames + 1, 0 ); + assert( pSat->size == 2 * pCnf->nVars ); + // add clauses to the first frame + Beg = 0; + pStart = Vec_IntArray( vLits ); + Vec_IntForEachEntry( vClauses, End, i ) + { + RetValue = sat_solver_addclause( pSat, pStart + Beg, pStart + End ); + Beg = End; + if ( RetValue == 0 ) + { + Cnf_DataFree( pCnf ); + sat_solver_delete( pSat ); + printf( "Invariant verification: SAT solver is unsat after adding a clause.\n" ); + return 0; + } + } + // simplify the solver + if ( pSat->qtail != pSat->qhead ) + { + RetValue = sat_solver_simplify(pSat); + assert( RetValue != 0 ); + assert( pSat->qtail == pSat->qhead ); + } + + // check clauses in the base case + Beg = 0; + pStart = Vec_IntArray( vLits ); + Vec_IntForEachEntry( vClauses, End, i ) + { + // complement the literals + for ( k = Beg; k < End; k++ ) + { + pStart[k] += 2 * pCnf->nVars; + pStart[k] = lit_neg(pStart[k]); + } + RetValue = sat_solver_solve( pSat, pStart + Beg, pStart + End, 0, 0, 0, 0 ); + for ( k = Beg; k < End; k++ ) + { + pStart[k] = lit_neg(pStart[k]); + pStart[k] -= 2 * pCnf->nVars; + } + Beg = End; + if ( RetValue == l_False ) + continue; +// printf( "Clause %d failed the inductive case.\n", i ); + CounterInd++; + } + sat_solver_delete( pSat ); + Cnf_DataFree( pCnf ); + if ( CounterBase ) + printf( "Invariant verification: %d clauses (out of %d) FAILED the base case.\n", CounterBase, Vec_IntSize(vClauses) ); + if ( CounterInd ) + printf( "Invariant verification: %d clauses (out of %d) FAILED the inductive case.\n", CounterInd, Vec_IntSize(vClauses) ); + if ( CounterBase || CounterInd ) + return 0; + printf( "Invariant verification: %d clauses verified correctly. ", Vec_IntSize(vClauses) ); + PRT( "Time", clock() - clk ); + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/fra/fraMan.c b/src/aig/fra/fraMan.c index f505b0c2..b06f98d4 100644 --- a/src/aig/fra/fraMan.c +++ b/src/aig/fra/fraMan.c @@ -251,6 +251,7 @@ void Fra_ManStop( Fra_Man_t * p ) if ( p->pCla ) Fra_ClassesStop( p->pCla ); if ( p->pSml ) Fra_SmlStop( p->pSml ); if ( p->vCex ) Vec_IntFree( p->vCex ); + if ( p->vOneHots ) Vec_IntFree( p->vOneHots ); FREE( p->pMemFraig ); FREE( p->pMemFanins ); FREE( p->pMemSatNums ); @@ -279,7 +280,8 @@ void Fra_ManPrint( Fra_Man_t * p ) printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", p->nNodesBeg, p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/(p->nNodesBeg?p->nNodesBeg:1), p->nRegsBeg, p->nRegsEnd, 100.0*(p->nRegsBeg-p->nRegsEnd)/(p->nRegsBeg?p->nRegsBeg:1) ); - if ( p->pSat ) Sat_SolverPrintStats( stdout, p->pSat ); + if ( p->pSat ) Sat_SolverPrintStats( stdout, p->pSat ); + if ( p->pPars->fUse1Hot ) Fra_OneHotEstimateCoverage( p, p->vOneHots ); PRT( "AIG simulation ", p->pSml->timeSim ); PRT( "AIG traversal ", p->timeTrav ); if ( p->timeRwr ) diff --git a/src/aig/fra/fraSat.c b/src/aig/fra/fraSat.c index 819605d6..8332fa77 100644 --- a/src/aig/fra/fraSat.c +++ b/src/aig/fra/fraSat.c @@ -300,6 +300,113 @@ p->timeSatFail += clock() - clk; /**Function************************************************************* + Synopsis [Runs the result of test for pObj => pNew.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_NodesAreClause( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew, int fComplL, int fComplR ) +{ + int pLits[4], RetValue, RetValue1, nBTLimit, clk;//, clk2 = clock(); + int status; + + // make sure the nodes are not complemented + assert( !Aig_IsComplement(pNew) ); + assert( !Aig_IsComplement(pOld) ); + assert( pNew != pOld ); + + // if at least one of the nodes is a failed node, perform adjustments: + // if the backtrack limit is small, simply skip this node + // if the backtrack limit is > 10, take the quare root of the limit + nBTLimit = p->pPars->nBTLimitNode; +/* + if ( !p->pPars->fSpeculate && p->pPars->nFramesK == 0 && (nBTLimit > 0 && (pOld->fMarkB || pNew->fMarkB)) ) + { + p->nSatFails++; + // fail immediately +// return -1; + if ( nBTLimit <= 10 ) + return -1; + nBTLimit = (int)pow(nBTLimit, 0.7); + } +*/ + p->nSatCalls++; + + // make sure the solver is allocated and has enough variables + if ( p->pSat == NULL ) + { + p->pSat = sat_solver_new(); + p->nSatVars = 1; + sat_solver_setnvars( p->pSat, 1000 ); + // var 0 is reserved for const1 node - add the clause + pLits[0] = toLit( 0 ); + sat_solver_addclause( p->pSat, pLits, pLits + 1 ); + } + + // if the nodes do not have SAT variables, allocate them + Fra_CnfNodeAddToSolver( p, pOld, pNew ); + + if ( p->pSat->qtail != p->pSat->qhead ) + { + status = sat_solver_simplify(p->pSat); + assert( status != 0 ); + assert( p->pSat->qtail == p->pSat->qhead ); + } + + // prepare variable activity + if ( p->pPars->fConeBias ) + Fra_SetActivityFactors( p, pOld, pNew ); + + // solve under assumptions + // A = 1; B = 0 OR A = 1; B = 1 +clk = clock(); +// pLits[0] = toLitCond( Fra_ObjSatNum(pOld), 0 ); +// pLits[1] = toLitCond( Fra_ObjSatNum(pNew), pOld->fPhase == pNew->fPhase ); + pLits[0] = toLitCond( Fra_ObjSatNum(pOld), !fComplL ); + pLits[1] = toLitCond( Fra_ObjSatNum(pNew), !fComplR ); +//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 ); + RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + 2, + (sint64)nBTLimit, (sint64)0, + p->nBTLimitGlobal, p->nInsLimitGlobal ); +p->timeSat += clock() - clk; + if ( RetValue1 == l_False ) + { +p->timeSatUnsat += clock() - clk; + pLits[0] = lit_neg( pLits[0] ); + pLits[1] = lit_neg( pLits[1] ); + RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); + assert( RetValue ); + // continue solving the other implication + p->nSatCallsUnsat++; + } + else if ( RetValue1 == l_True ) + { +p->timeSatSat += clock() - clk; + Fra_SmlSavePattern( p ); + p->nSatCallsSat++; + return 0; + } + else // if ( RetValue1 == l_Undef ) + { +p->timeSatFail += clock() - clk; + // mark the node as the failed node + if ( pOld != p->pManFraig->pConst1 ) + pOld->fMarkB = 1; + pNew->fMarkB = 1; + p->nSatFailsReal++; + return -1; + } + // return SAT proof + p->nSatProof++; + return 1; +} + +/**Function************************************************************* + Synopsis [Runs equivalence test for one node.] Description [Returns the fraiged node.] diff --git a/src/aig/fra/fraSec.c b/src/aig/fra/fraSec.c index c6bdc20e..3e0fca6a 100644 --- a/src/aig/fra/fraSec.c +++ b/src/aig/fra/fraSec.c @@ -49,7 +49,7 @@ int Fra_FraigSec2( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose { nFrames = nFramesFix; // perform seq sweeping for one frame number - pNew = Fra_FraigInduction( p, 0, nFrames, 0, 0, 0, 0, fLatchCorr, 0, fVeryVerbose, &nIter ); + pNew = Fra_FraigInduction( p, 0, nFrames, 0, 0, 0, 0, fLatchCorr, 0, 0, fVeryVerbose, &nIter ); } else { @@ -57,7 +57,7 @@ int Fra_FraigSec2( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose for ( nFrames = 1; ; nFrames++ ) { clk = clock(); - pNew = Fra_FraigInduction( p, 0, nFrames, 0, 0, 0, 0, fLatchCorr, 0, fVeryVerbose, &nIter ); + pNew = Fra_FraigInduction( p, 0, nFrames, 0, 0, 0, 0, fLatchCorr, 0, 0, fVeryVerbose, &nIter ); RetValue = Fra_FraigMiterStatus( pNew ); if ( fVerbose ) { @@ -185,7 +185,7 @@ PRT( "Time", clock() - clk ); for ( nFrames = 1; nFrames <= nFramesMax; nFrames *= 2 ) { clk = clock(); - pNew = Fra_FraigInduction( pTemp = pNew, 0, nFrames, 0, 0, 0, 0, fLatchCorr, 0, fVeryVerbose, &nIter ); + pNew = Fra_FraigInduction( pTemp = pNew, 0, nFrames, 0, 0, 0, 0, fLatchCorr, 0, 0, fVeryVerbose, &nIter ); Aig_ManStop( pTemp ); RetValue = Fra_FraigMiterStatus( pNew ); if ( fVerbose ) diff --git a/src/aig/fra/fraSim.c b/src/aig/fra/fraSim.c index 1ad2d4f7..fe11ac36 100644 --- a/src/aig/fra/fraSim.c +++ b/src/aig/fra/fraSim.c @@ -657,6 +657,8 @@ clk = clock(); nChanges += Fra_ClassesRefine1( p->pCla, 1, NULL ); if ( p->pCla->vImps ) nChanges += Fra_ImpRefineUsingCex( p, p->pCla->vImps ); + if ( p->vOneHots ) + nChanges += Fra_OneHotRefineUsingCex( p, p->vOneHots ); p->timeRef += clock() - clk; if ( !p->pPars->nFramesK && nChanges < 1 ) printf( "Error: A counter-example did not refine classes!\n" ); diff --git a/src/aig/fra/module.make b/src/aig/fra/module.make index ffaca75c..e3a88aae 100644 --- a/src/aig/fra/module.make +++ b/src/aig/fra/module.make @@ -5,8 +5,10 @@ SRC += src/aig/fra/fraBmc.c \ src/aig/fra/fraClaus.c \ src/aig/fra/fraCnf.c \ src/aig/fra/fraCore.c \ + src/aig/fra/fraHot.c \ src/aig/fra/fraImp.c \ src/aig/fra/fraInd.c \ + src/aig/fra/fraIndVer.c \ src/aig/fra/fraLcr.c \ src/aig/fra/fraMan.c \ src/aig/fra/fraPart.c \ |