diff options
Diffstat (limited to 'src/proof/fra/fraClaus.c')
-rw-r--r-- | src/proof/fra/fraClaus.c | 1875 |
1 files changed, 1875 insertions, 0 deletions
diff --git a/src/proof/fra/fraClaus.c b/src/proof/fra/fraClaus.c new file mode 100644 index 00000000..e71219b5 --- /dev/null +++ b/src/proof/fra/fraClaus.c @@ -0,0 +1,1875 @@ +/**CFile**************************************************************** + + FileName [fraClaus.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [New FRAIG package.] + + Synopsis [Induction with clause strengthening.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 30, 2007.] + + Revision [$Id: fraClau.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fra.h" +#include "src/sat/cnf/cnf.h" +#include "src/sat/bsat/satSolver.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Clu_Man_t_ Clu_Man_t; +struct Clu_Man_t_ +{ + // parameters + int nFrames; // the K of the K-step induction + int nPref; // the number of timeframes to skip + int nClausesMax; // the max number of 4-clauses to consider + int nLutSize; // the max cut size + int nLevels; // the number of levels for cut computation + int nCutsMax; // the maximum number of cuts to compute at a node + int nBatches; // the number of clause batches to use + int fStepUp; // increase cut size for each batch + int fTarget; // tries to prove the property + int fVerbose; + int fVeryVerbose; + // internal parameters + int nSimWords; // the number of simulation words + int nSimWordsPref; // the number of simulation words in the prefix + int nSimFrames; // the number of frames to simulate + int nBTLimit; // the largest number of backtracks (0 = infinite) + // the network + Aig_Man_t * pAig; + // SAT solvers + sat_solver * pSatMain; + sat_solver * pSatBmc; + // CNF for the test solver + Cnf_Dat_t * pCnf; + int fFail; + int fFiltering; + int fNothingNew; + // clauses + Vec_Int_t * vLits; + Vec_Int_t * vClauses; + Vec_Int_t * vCosts; + int nClauses; + int nCuts; + int nOneHots; + int nOneHotsProven; + // clauses proven + Vec_Int_t * vLitsProven; + Vec_Int_t * vClausesProven; + // counter-examples + Vec_Ptr_t * vCexes; + int nCexes; + int nCexesAlloc; +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Runs the SAT solver on the problem.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausRunBmc( Clu_Man_t * p ) +{ + Aig_Obj_t * pObj; + int Lits[2], nLitsTot, RetValue, i; + // set the output literals + nLitsTot = 2 * p->pCnf->nVars; + pObj = Aig_ManPo(p->pAig, 0); + for ( i = 0; i < p->nPref + p->nFrames; i++ ) + { + Lits[0] = i * nLitsTot + toLitCond( p->pCnf->pVarNums[pObj->Id], 0 ); + RetValue = sat_solver_solve( p->pSatBmc, Lits, Lits + 1, (ABC_INT64_T)p->nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( RetValue != l_False ) + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Runs the SAT solver on the problem.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausRunSat( Clu_Man_t * p ) +{ + Aig_Obj_t * pObj; + int * pLits; + int i, RetValue; + pLits = ABC_ALLOC( int, p->nFrames + 1 ); + // set the output literals + pObj = Aig_ManPo(p->pAig, 0); + for ( i = 0; i <= p->nFrames; i++ ) + pLits[i] = i * 2 * p->pCnf->nVars + toLitCond( p->pCnf->pVarNums[pObj->Id], i != p->nFrames ); + // try to solve the problem + RetValue = sat_solver_solve( p->pSatMain, pLits, pLits + p->nFrames + 1, (ABC_INT64_T)p->nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + ABC_FREE( pLits ); + if ( RetValue == l_False ) + return 1; + // get the counter-example + assert( RetValue == l_True ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Runs the SAT solver on the problem.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausRunSat0( Clu_Man_t * p ) +{ + Aig_Obj_t * pObj; + int Lits[2], RetValue; + pObj = Aig_ManPo(p->pAig, 0); + Lits[0] = toLitCond( p->pCnf->pVarNums[pObj->Id], 0 ); + RetValue = sat_solver_solve( p->pSatMain, Lits, Lits + 1, (ABC_INT64_T)p->nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + if ( RetValue == l_False ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Return combinations appearing in the cut.] + + Description [This procedure is taken from "Hacker's Delight" by H.S.Warren.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void transpose32a( unsigned a[32] ) +{ + int j, k; + unsigned long m, t; + for ( j = 16, m = 0x0000FFFF; j; j >>= 1, m ^= m << j ) + { + for ( k = 0; k < 32; k = ((k | j) + 1) & ~j ) + { + t = (a[k] ^ (a[k|j] >> j)) & m; + a[k] ^= t; + a[k|j] ^= (t << j); + } + } +} + +/**Function************************************************************* + + Synopsis [Return combinations appearing in the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausProcessClausesCut( Clu_Man_t * p, Fra_Sml_t * pSimMan, Dar_Cut_t * pCut, int * pScores ) +{ + unsigned Matrix[32]; + unsigned * pSims[16], uWord; + int nSeries, i, k, j; + int nWordsForSim = pSimMan->nWordsTotal - p->nSimWordsPref; + // compute parameters + assert( pCut->nLeaves > 1 && pCut->nLeaves < 5 ); + assert( nWordsForSim % 8 == 0 ); + // get parameters + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + pSims[i] = Fra_ObjSim( pSimMan, pCut->pLeaves[i] ) + p->nSimWordsPref; + // add combinational patterns + memset( pScores, 0, sizeof(int) * 16 ); + nSeries = nWordsForSim / 8; + for ( i = 0; i < nSeries; i++ ) + { + memset( Matrix, 0, sizeof(unsigned) * 32 ); + for ( k = 0; k < 8; k++ ) + for ( j = 0; j < (int)pCut->nLeaves; j++ ) + Matrix[31-(k*4+j)] = pSims[j][i*8+k]; + transpose32a( Matrix ); + for ( k = 0; k < 32; k++ ) + for ( j = 0, uWord = Matrix[k]; j < 8; j++, uWord >>= 4 ) + pScores[uWord & 0xF]++; + } + // collect patterns + uWord = 0; + for ( i = 0; i < 16; i++ ) + if ( pScores[i] ) + uWord |= (1 << i); +// Extra_PrintBinary( stdout, &uWord, 16 ); printf( "\n" ); + return (int)uWord; +} + +/**Function************************************************************* + + Synopsis [Return combinations appearing in the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausProcessClausesCut2( Clu_Man_t * p, Fra_Sml_t * pSimMan, Dar_Cut_t * pCut, int * pScores ) +{ + unsigned * pSims[16], uWord; + int iMint, i, k, b; + int nWordsForSim = pSimMan->nWordsTotal - p->nSimWordsPref; + // compute parameters + assert( pCut->nLeaves > 1 && pCut->nLeaves < 5 ); + assert( nWordsForSim % 8 == 0 ); + // get parameters + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + pSims[i] = Fra_ObjSim( pSimMan, pCut->pLeaves[i] ) + p->nSimWordsPref; + // add combinational patterns + memset( pScores, 0, sizeof(int) * 16 ); + for ( i = 0; i < nWordsForSim; i++ ) + for ( k = 0; k < 32; k++ ) + { + iMint = 0; + for ( b = 0; b < (int)pCut->nLeaves; b++ ) + if ( pSims[b][i] & (1 << k) ) + iMint |= (1 << b); + pScores[iMint]++; + } + // collect patterns + uWord = 0; + for ( i = 0; i < 16; i++ ) + if ( pScores[i] ) + uWord |= (1 << i); +// Extra_PrintBinary( stdout, &uWord, 16 ); printf( "\n" ); + return (int)uWord; +} + +/**Function************************************************************* + + Synopsis [Return the number of combinations appearing in the cut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fra_ClausProcessClausesCut3( Clu_Man_t * p, Fra_Sml_t * pSimMan, Aig_Cut_t * pCut, int * pScores ) +{ + unsigned Matrix[32]; + unsigned * pSims[16], uWord; + int iMint, i, j, k, b, nMints, nSeries; + int nWordsForSim = pSimMan->nWordsTotal - p->nSimWordsPref; + + // compute parameters + assert( pCut->nFanins > 1 && pCut->nFanins < 17 ); + assert( nWordsForSim % 8 == 0 ); + // get parameters + for ( i = 0; i < (int)pCut->nFanins; i++ ) + pSims[i] = Fra_ObjSim( pSimMan, pCut->pFanins[i] ) + p->nSimWordsPref; + // add combinational patterns + nMints = (1 << pCut->nFanins); + memset( pScores, 0, sizeof(int) * nMints ); + + if ( pCut->nLeafMax == 4 ) + { + // convert the simulation patterns + nSeries = nWordsForSim / 8; + for ( i = 0; i < nSeries; i++ ) + { + memset( Matrix, 0, sizeof(unsigned) * 32 ); + for ( k = 0; k < 8; k++ ) + for ( j = 0; j < (int)pCut->nFanins; j++ ) + Matrix[31-(k*4+j)] = pSims[j][i*8+k]; + transpose32a( Matrix ); + for ( k = 0; k < 32; k++ ) + for ( j = 0, uWord = Matrix[k]; j < 8; j++, uWord >>= 4 ) + pScores[uWord & 0xF]++; + } + } + else + { + // go through the simulation patterns + for ( i = 0; i < nWordsForSim; i++ ) + for ( k = 0; k < 32; k++ ) + { + iMint = 0; + for ( b = 0; b < (int)pCut->nFanins; b++ ) + if ( pSims[b][i] & (1 << k) ) + iMint |= (1 << b); + pScores[iMint]++; + } + } +} + + +/**Function************************************************************* + + Synopsis [Returns the cut-off cost.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausSelectClauses( Clu_Man_t * p ) +{ + int * pCostCount, nClauCount, Cost, CostMax, i, c; + assert( Vec_IntSize(p->vClauses) > p->nClausesMax ); + // count how many implications have each cost + CostMax = p->nSimWords * 32 + 1; + pCostCount = ABC_ALLOC( int, CostMax ); + memset( pCostCount, 0, sizeof(int) * CostMax ); + Vec_IntForEachEntry( p->vCosts, Cost, i ) + { + if ( Cost == -1 ) + continue; + assert( Cost < CostMax ); + pCostCount[ Cost ]++; + } + assert( pCostCount[0] == 0 ); + // select the bound on the cost (above this bound, implication will be included) + nClauCount = 0; + for ( c = CostMax - 1; c > 0; c-- ) + { + assert( pCostCount[c] >= 0 ); + nClauCount += pCostCount[c]; + if ( nClauCount >= p->nClausesMax ) + break; + } + // collect implications with the given costs + nClauCount = 0; + Vec_IntForEachEntry( p->vCosts, Cost, i ) + { + if ( Cost >= c && nClauCount < p->nClausesMax ) + { + nClauCount++; + continue; + } + Vec_IntWriteEntry( p->vCosts, i, -1 ); + } + ABC_FREE( pCostCount ); + p->nClauses = nClauCount; +if ( p->fVerbose ) +printf( "Selected %d clauses. Cost range: [%d < %d < %d]\n", nClauCount, 1, c, CostMax ); + return c; +} + + +/**Function************************************************************* + + Synopsis [Processes the clauses.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fra_ClausRecordClause( Clu_Man_t * p, Dar_Cut_t * pCut, int iMint, int Cost ) +{ + int i; + for ( i = 0; i < (int)pCut->nLeaves; i++ ) + Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pCut->pLeaves[i]], (iMint&(1<<i)) ) ); + Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) ); + Vec_IntPush( p->vCosts, Cost ); +} + +/**Function************************************************************* + + Synopsis [Processes the clauses.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fra_ClausRecordClause2( Clu_Man_t * p, Aig_Cut_t * pCut, int iMint, int Cost ) +{ + int i; + for ( i = 0; i < (int)pCut->nFanins; i++ ) + Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pCut->pFanins[i]], (iMint&(1<<i)) ) ); + Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) ); + Vec_IntPush( p->vCosts, Cost ); +} + +/**Function************************************************************* + + Synopsis [Returns 1 if simulation info is composed of all zeros.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausSmlNodeIsConst( 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 implications holds.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausSmlNodesAreImp( Fra_Sml_t * pSeq, Aig_Obj_t * pObj1, Aig_Obj_t * pObj2 ) +{ + unsigned * pSimL, * pSimR; + int k; + pSimL = Fra_ObjSim(pSeq, pObj1->Id); + pSimR = Fra_ObjSim(pSeq, pObj2->Id); + for ( k = pSeq->nWordsPref; k < pSeq->nWordsTotal; k++ ) + if ( pSimL[k] & ~pSimR[k] ) // !(Obj1 -> Obj2) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if implications holds.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausSmlNodesAreImpC( Fra_Sml_t * pSeq, Aig_Obj_t * pObj1, Aig_Obj_t * pObj2 ) +{ + unsigned * pSimL, * pSimR; + int k; + pSimL = Fra_ObjSim(pSeq, pObj1->Id); + pSimR = Fra_ObjSim(pSeq, pObj2->Id); + for ( k = pSeq->nWordsPref; k < pSeq->nWordsTotal; k++ ) + if ( pSimL[k] & pSimR[k] ) + return 0; + return 1; +} + +/**Function************************************************************* + + Synopsis [Processes the clauses.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausCollectLatchClauses( Clu_Man_t * p, Fra_Sml_t * pSeq ) +{ + Aig_Obj_t * pObj1, * pObj2; + unsigned * pSims1, * pSims2; + int CostMax, i, k, nCountConst, nCountImps; + + 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 ) + { + pSims1 = Fra_ObjSim( pSeq, pObj1->Id ); + if ( Fra_ClausSmlNodeIsConst( pSeq, pObj1 ) ) + { + Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj1->Id], 1 ) ); + Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) ); + Vec_IntPush( p->vCosts, CostMax ); + nCountConst++; + continue; + } + Aig_ManForEachLoSeq( p->pAig, pObj2, k ) + { + pSims2 = Fra_ObjSim( pSeq, pObj2->Id ); + if ( Fra_ClausSmlNodesAreImp( pSeq, pObj1, pObj2 ) ) + { + Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj1->Id], 1 ) ); + Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj2->Id], 0 ) ); + Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) ); + Vec_IntPush( p->vCosts, CostMax ); + nCountImps++; + continue; + } + if ( Fra_ClausSmlNodesAreImp( pSeq, pObj2, pObj1 ) ) + { + Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj2->Id], 1 ) ); + Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj1->Id], 0 ) ); + Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) ); + Vec_IntPush( p->vCosts, CostMax ); + nCountImps++; + continue; + } + if ( Fra_ClausSmlNodesAreImpC( pSeq, pObj1, pObj2 ) ) + { + Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj1->Id], 1 ) ); + Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj2->Id], 1 ) ); + Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) ); + Vec_IntPush( p->vCosts, CostMax ); + nCountImps++; + continue; + } + } + if ( nCountConst + nCountImps > p->nClausesMax / 2 ) + break; + } + pSeq->nWordsPref = 0; + if ( p->fVerbose ) + printf( "Collected %d register constants and %d one-hotness implications.\n", nCountConst, nCountImps ); + p->nOneHots = nCountConst + nCountImps; + p->nOneHotsProven = 0; + return 0; +} + +/**Function************************************************************* + + Synopsis [Processes the clauses.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausProcessClauses( Clu_Man_t * p, int fRefs ) +{ + Aig_MmFixed_t * pMemCuts; +// Aig_ManCut_t * pManCut; + Fra_Sml_t * pComb, * pSeq; + Aig_Obj_t * pObj; + Dar_Cut_t * pCut; + int Scores[16], uScores, i, k, j, clk, nCuts = 0; + + // simulate the AIG +clk = clock(); +// srand( 0xAABBAABB ); + Aig_ManRandom(1); + pSeq = Fra_SmlSimulateSeq( p->pAig, 0, p->nPref + p->nSimFrames, p->nSimWords/p->nSimFrames, 1 ); + if ( p->fTarget && pSeq->fNonConstOut ) + { + printf( "Property failed after sequential simulation!\n" ); + Fra_SmlStop( pSeq ); + return 0; + } +if ( p->fVerbose ) +{ +ABC_PRT( "Sim-seq", clock() - clk ); +} + + +clk = clock(); + if ( fRefs ) + { + Fra_ClausCollectLatchClauses( p, pSeq ); +if ( p->fVerbose ) +{ +ABC_PRT( "Lat-cla", clock() - clk ); +} + } + + + // generate cuts for all nodes, assign cost, and find best cuts +clk = clock(); + pMemCuts = Dar_ManComputeCuts( p->pAig, 10, 1 ); +// pManCut = Aig_ComputeCuts( p->pAig, 10, 4, 0, 1 ); +if ( p->fVerbose ) +{ +ABC_PRT( "Cuts ", clock() - clk ); +} + + // collect sequential info for each cut +clk = clock(); + Aig_ManForEachNode( p->pAig, pObj, i ) + Dar_ObjForEachCut( pObj, pCut, k ) + if ( pCut->nLeaves > 1 ) + { + pCut->uTruth = Fra_ClausProcessClausesCut( p, pSeq, pCut, Scores ); +// uScores = Fra_ClausProcessClausesCut2( p, pSeq, pCut, Scores ); +// if ( uScores != pCut->uTruth ) +// { +// int x = 0; +// } + } +if ( p->fVerbose ) +{ +ABC_PRT( "Infoseq", clock() - clk ); +} + Fra_SmlStop( pSeq ); + + // perform combinational simulation +clk = clock(); +// srand( 0xAABBAABB ); + Aig_ManRandom(1); + pComb = Fra_SmlSimulateComb( p->pAig, p->nSimWords + p->nSimWordsPref ); +if ( p->fVerbose ) +{ +ABC_PRT( "Sim-cmb", clock() - clk ); +} + + // collect combinational info for each cut +clk = clock(); + Aig_ManForEachNode( p->pAig, pObj, i ) + Dar_ObjForEachCut( pObj, pCut, k ) + if ( pCut->nLeaves > 1 ) + { + nCuts++; + uScores = Fra_ClausProcessClausesCut( p, pComb, pCut, Scores ); + uScores &= ~pCut->uTruth; pCut->uTruth = 0; + if ( uScores == 0 ) + continue; + // write the clauses + for ( j = 0; j < (1<<pCut->nLeaves); j++ ) + if ( uScores & (1 << j) ) + Fra_ClausRecordClause( p, pCut, j, Scores[j] ); + + } + Fra_SmlStop( pComb ); + Aig_MmFixedStop( pMemCuts, 0 ); +// Aig_ManCutStop( pManCut ); +if ( p->fVerbose ) +{ +ABC_PRT( "Infocmb", clock() - clk ); +} + + if ( p->fVerbose ) + printf( "Node = %5d. Non-triv cuts = %7d. Clauses = %6d. Clause per cut = %6.2f.\n", + Aig_ManNodeNum(p->pAig), nCuts, Vec_IntSize(p->vClauses), 1.0*Vec_IntSize(p->vClauses)/nCuts ); + + if ( Vec_IntSize(p->vClauses) > p->nClausesMax ) + Fra_ClausSelectClauses( p ); + else + p->nClauses = Vec_IntSize( p->vClauses ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Processes the clauses.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausProcessClauses2( Clu_Man_t * p, int fRefs ) +{ +// Aig_MmFixed_t * pMemCuts; + Aig_ManCut_t * pManCut; + Fra_Sml_t * pComb, * pSeq; + Aig_Obj_t * pObj; + Aig_Cut_t * pCut; + int i, k, j, clk, nCuts = 0; + int ScoresSeq[1<<12], ScoresComb[1<<12]; + assert( p->nLutSize < 13 ); + + // simulate the AIG +clk = clock(); +// srand( 0xAABBAABB ); + Aig_ManRandom(1); + pSeq = Fra_SmlSimulateSeq( p->pAig, 0, p->nPref + p->nSimFrames, p->nSimWords/p->nSimFrames, 1 ); + if ( p->fTarget && pSeq->fNonConstOut ) + { + printf( "Property failed after sequential simulation!\n" ); + Fra_SmlStop( pSeq ); + return 0; + } +if ( p->fVerbose ) +{ +//ABC_PRT( "Sim-seq", clock() - clk ); +} + + // perform combinational simulation +clk = clock(); +// srand( 0xAABBAABB ); + Aig_ManRandom(1); + pComb = Fra_SmlSimulateComb( p->pAig, p->nSimWords + p->nSimWordsPref ); +if ( p->fVerbose ) +{ +//ABC_PRT( "Sim-cmb", clock() - clk ); +} + + +clk = clock(); + if ( fRefs ) + { + Fra_ClausCollectLatchClauses( p, pSeq ); +if ( p->fVerbose ) +{ +//ABC_PRT( "Lat-cla", clock() - clk ); +} + } + + + // generate cuts for all nodes, assign cost, and find best cuts +clk = clock(); +// pMemCuts = Dar_ManComputeCuts( p->pAig, 10, 1 ); + pManCut = Aig_ComputeCuts( p->pAig, p->nCutsMax, p->nLutSize, 0, p->fVerbose ); +if ( p->fVerbose ) +{ +//ABC_PRT( "Cuts ", clock() - clk ); +} + + // collect combinational info for each cut +clk = clock(); + Aig_ManForEachNode( p->pAig, pObj, i ) + { + if ( pObj->Level > (unsigned)p->nLevels ) + continue; + Aig_ObjForEachCut( pManCut, pObj, pCut, k ) + if ( pCut->nFanins > 1 ) + { + nCuts++; + Fra_ClausProcessClausesCut3( p, pSeq, pCut, ScoresSeq ); + Fra_ClausProcessClausesCut3( p, pComb, pCut, ScoresComb ); + // write the clauses + for ( j = 0; j < (1<<pCut->nFanins); j++ ) + if ( ScoresComb[j] != 0 && ScoresSeq[j] == 0 ) + Fra_ClausRecordClause2( p, pCut, j, ScoresComb[j] ); + + } + } + Fra_SmlStop( pSeq ); + Fra_SmlStop( pComb ); + p->nCuts = nCuts; +// Aig_MmFixedStop( pMemCuts, 0 ); + Aig_ManCutStop( pManCut ); + p->pAig->pManCuts = NULL; + + if ( p->fVerbose ) + { + printf( "Node = %5d. Cuts = %7d. Clauses = %6d. Clause/cut = %6.2f.\n", + Aig_ManNodeNum(p->pAig), nCuts, Vec_IntSize(p->vClauses), 1.0*Vec_IntSize(p->vClauses)/nCuts ); + ABC_PRT( "Processing sim-info to find candidate clauses (unoptimized)", clock() - clk ); + } + + // filter out clauses that are contained in the already proven clauses + assert( p->nClauses == 0 ); + p->nClauses = Vec_IntSize( p->vClauses ); + if ( Vec_IntSize( p->vClausesProven ) > 0 ) + { + int RetValue, k, Beg; + int End = -1; // Suppress "might be used uninitialized" + int * pStart; + // reset the solver + if ( p->pSatMain ) sat_solver_delete( p->pSatMain ); + p->pSatMain = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 ); + if ( p->pSatMain == NULL ) + { + printf( "Error: Main solver is unsat.\n" ); + return -1; + } + + // add the proven clauses + Beg = 0; + pStart = Vec_IntArray(p->vLitsProven); + Vec_IntForEachEntry( p->vClausesProven, End, i ) + { + assert( End - Beg <= p->nLutSize ); + // add the clause to all timeframes + RetValue = sat_solver_addclause( p->pSatMain, pStart + Beg, pStart + End ); + if ( RetValue == 0 ) + { + printf( "Error: Solver is UNSAT after adding assumption clauses.\n" ); + return -1; + } + Beg = End; + } + assert( End == Vec_IntSize(p->vLitsProven) ); + + // check the clauses + Beg = 0; + pStart = Vec_IntArray(p->vLits); + Vec_IntForEachEntry( p->vClauses, End, i ) + { + assert( Vec_IntEntry( p->vCosts, i ) >= 0 ); + assert( End - Beg <= p->nLutSize ); + // check the clause + for ( k = Beg; k < End; k++ ) + pStart[k] = lit_neg( pStart[k] ); + RetValue = sat_solver_solve( p->pSatMain, pStart + Beg, pStart + End, (ABC_INT64_T)p->nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + for ( k = Beg; k < End; k++ ) + pStart[k] = lit_neg( pStart[k] ); + // the clause holds + if ( RetValue == l_False ) + { + Vec_IntWriteEntry( p->vCosts, i, -1 ); + p->nClauses--; + } + Beg = End; + } + assert( End == Vec_IntSize(p->vLits) ); + if ( p->fVerbose ) + printf( "Already proved clauses filtered out %d candidate clauses (out of %d).\n", + Vec_IntSize(p->vClauses) - p->nClauses, Vec_IntSize(p->vClauses) ); + } + + p->fFiltering = 0; + if ( p->nClauses > p->nClausesMax ) + { + Fra_ClausSelectClauses( p ); + p->fFiltering = 1; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Converts AIG into the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausBmcClauses( Clu_Man_t * p ) +{ + int * pStart, nLitsTot, RetValue, Beg, End, Counter, i, k, f; +/* + for ( i = 0; i < Vec_IntSize(p->vLits); i++ ) + printf( "%d ", p->vLits->pArray[i] ); + printf( "\n" ); +*/ + // add the clauses + Counter = 0; + // skip through the prefix variables + if ( p->nPref ) + { + nLitsTot = p->nPref * 2 * p->pCnf->nVars; + for ( i = 0; i < Vec_IntSize(p->vLits); i++ ) + p->vLits->pArray[i] += nLitsTot; + } + // go through the timeframes + nLitsTot = 2 * p->pCnf->nVars; + pStart = Vec_IntArray(p->vLits); + for ( f = 0; f < p->nFrames; f++ ) + { + Beg = 0; + Vec_IntForEachEntry( p->vClauses, End, i ) + { + if ( Vec_IntEntry( p->vCosts, i ) == -1 ) + { + Beg = End; + continue; + } + assert( Vec_IntEntry( p->vCosts, i ) > 0 ); + assert( End - Beg <= p->nLutSize ); + + for ( k = Beg; k < End; k++ ) + pStart[k] = lit_neg( pStart[k] ); + RetValue = sat_solver_solve( p->pSatBmc, pStart + Beg, pStart + End, (ABC_INT64_T)p->nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + for ( k = Beg; k < End; k++ ) + pStart[k] = lit_neg( pStart[k] ); + + if ( RetValue != l_False ) + { + Beg = End; + Vec_IntWriteEntry( p->vCosts, i, -1 ); + Counter++; + continue; + } +/* + // add the clause + RetValue = sat_solver_addclause( p->pSatBmc, pStart + Beg, pStart + End ); + // assert( RetValue == 1 ); + if ( RetValue == 0 ) + { + printf( "Error: Solver is UNSAT after adding BMC clauses.\n" ); + return -1; + } +*/ + Beg = End; + + // simplify the solver + if ( p->pSatBmc->qtail != p->pSatBmc->qhead ) + { + RetValue = sat_solver_simplify(p->pSatBmc); + assert( RetValue != 0 ); + assert( p->pSatBmc->qtail == p->pSatBmc->qhead ); + } + } + // increment literals + for ( i = 0; i < Vec_IntSize(p->vLits); i++ ) + p->vLits->pArray[i] += nLitsTot; + } + + // return clauses back to normal + nLitsTot = (p->nPref + p->nFrames) * nLitsTot; + for ( i = 0; i < Vec_IntSize(p->vLits); i++ ) + p->vLits->pArray[i] -= nLitsTot; +/* + for ( i = 0; i < Vec_IntSize(p->vLits); i++ ) + printf( "%d ", p->vLits->pArray[i] ); + printf( "\n" ); +*/ + return Counter; +} + +/**Function************************************************************* + + Synopsis [Cleans simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fra_ClausSimInfoClean( Clu_Man_t * p ) +{ + assert( p->pCnf->nVars <= Vec_PtrSize(p->vCexes) ); + Vec_PtrCleanSimInfo( p->vCexes, 0, p->nCexesAlloc/32 ); + p->nCexes = 0; +} + +/**Function************************************************************* + + Synopsis [Reallocs simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fra_ClausSimInfoRealloc( Clu_Man_t * p ) +{ + assert( p->nCexes == p->nCexesAlloc ); + Vec_PtrReallocSimInfo( p->vCexes ); + Vec_PtrCleanSimInfo( p->vCexes, p->nCexesAlloc/32, 2 * p->nCexesAlloc/32 ); + p->nCexesAlloc *= 2; +} + +/**Function************************************************************* + + Synopsis [Records simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fra_ClausSimInfoRecord( Clu_Man_t * p, int * pModel ) +{ + int i; + if ( p->nCexes == p->nCexesAlloc ) + Fra_ClausSimInfoRealloc( p ); + assert( p->nCexes < p->nCexesAlloc ); + for ( i = 0; i < p->pCnf->nVars; i++ ) + { + if ( pModel[i] == l_True ) + { + assert( Abc_InfoHasBit( (unsigned *)Vec_PtrEntry(p->vCexes, i), p->nCexes ) == 0 ); + Abc_InfoSetBit( (unsigned *)Vec_PtrEntry(p->vCexes, i), p->nCexes ); + } + } + p->nCexes++; +} + +/**Function************************************************************* + + Synopsis [Uses the simulation info.] + + Description [Returns 1 if the simulation info disproved the clause.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausSimInfoCheck( Clu_Man_t * p, int * pLits, int nLits ) +{ + unsigned * pSims[16], uWord; + int nWords, iVar, i, w; + for ( i = 0; i < nLits; i++ ) + { + iVar = lit_var(pLits[i]) - p->nFrames * p->pCnf->nVars; + assert( iVar > 0 && iVar < p->pCnf->nVars ); + pSims[i] = (unsigned *)Vec_PtrEntry( p->vCexes, iVar ); + } + nWords = p->nCexes / 32; + for ( w = 0; w < nWords; w++ ) + { + uWord = ~(unsigned)0; + for ( i = 0; i < nLits; i++ ) + uWord &= (lit_sign(pLits[i])? pSims[i][w] : ~pSims[i][w]); + if ( uWord ) + return 1; + } + if ( p->nCexes % 32 ) + { + uWord = ~(unsigned)0; + for ( i = 0; i < nLits; i++ ) + uWord &= (lit_sign(pLits[i])? pSims[i][w] : ~pSims[i][w]); + if ( uWord & Abc_InfoMask( p->nCexes % 32 ) ) + return 1; + } + return 0; +} + + +/**Function************************************************************* + + Synopsis [Converts AIG into the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_ClausInductiveClauses( Clu_Man_t * p ) +{ +// Aig_Obj_t * pObjLi, * pObjLo; + int * pStart, nLitsTot, RetValue, Beg, End, Counter, i, k, f, fFlag;//, Lits[2]; + p->fFail = 0; + + // reset the solver + if ( p->pSatMain ) sat_solver_delete( p->pSatMain ); + p->pSatMain = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, p->nFrames+1, 0 ); + if ( p->pSatMain == NULL ) + { + printf( "Error: Main solver is unsat.\n" ); + return -1; + } + Fra_ClausSimInfoClean( p ); + +/* + // check if the property holds + if ( Fra_ClausRunSat0( p ) ) + printf( "Property holds without strengthening.\n" ); + else + printf( "Property does not hold without strengthening.\n" ); +*/ +/* + // add constant registers + Aig_ManForEachLiLoSeq( p->pAig, pObjLi, pObjLo, i ) + if ( Aig_ObjFanin0(pObjLi) == Aig_ManConst1(p->pAig) ) + { + for ( k = 0; k < p->nFrames; k++ ) + { + Lits[0] = k * 2 * p->pCnf->nVars + toLitCond( p->pCnf->pVarNums[pObjLo->Id], Aig_ObjFaninC0(pObjLi) ); + RetValue = sat_solver_addclause( p->pSatMain, Lits, Lits + 1 ); + if ( RetValue == 0 ) + { + printf( "Error: Solver is UNSAT after adding constant-register clauses.\n" ); + return -1; + } + } + } +*/ + + + // add the proven clauses + nLitsTot = 2 * p->pCnf->nVars; + pStart = Vec_IntArray(p->vLitsProven); + for ( f = 0; f < p->nFrames; f++ ) + { + Beg = 0; + Vec_IntForEachEntry( p->vClausesProven, End, i ) + { + assert( End - Beg <= p->nLutSize ); + // add the clause to all timeframes + RetValue = sat_solver_addclause( p->pSatMain, pStart + Beg, pStart + End ); + if ( RetValue == 0 ) + { + printf( "Error: Solver is UNSAT after adding assumption clauses.\n" ); + return -1; + } + Beg = End; + } + // increment literals + for ( i = 0; i < Vec_IntSize(p->vLitsProven); i++ ) + p->vLitsProven->pArray[i] += nLitsTot; + } + // return clauses back to normal + nLitsTot = (p->nFrames) * nLitsTot; + for ( i = 0; i < Vec_IntSize(p->vLitsProven); i++ ) + p->vLitsProven->pArray[i] -= nLitsTot; + +/* + // add the proven clauses + nLitsTot = 2 * p->pCnf->nVars; + pStart = Vec_IntArray(p->vLitsProven); + Beg = 0; + Vec_IntForEachEntry( p->vClausesProven, End, i ) + { + assert( End - Beg <= p->nLutSize ); + // add the clause to all timeframes + RetValue = sat_solver_addclause( p->pSatMain, pStart + Beg, pStart + End ); + if ( RetValue == 0 ) + { + printf( "Error: Solver is UNSAT after adding assumption clauses.\n" ); + return -1; + } + Beg = End; + } +*/ + + // add the clauses + nLitsTot = 2 * p->pCnf->nVars; + pStart = Vec_IntArray(p->vLits); + for ( f = 0; f < p->nFrames; f++ ) + { + Beg = 0; + Vec_IntForEachEntry( p->vClauses, End, i ) + { + if ( Vec_IntEntry( p->vCosts, i ) == -1 ) + { + Beg = End; + continue; + } + assert( Vec_IntEntry( p->vCosts, i ) > 0 ); + assert( End - Beg <= p->nLutSize ); + // add the clause to all timeframes + RetValue = sat_solver_addclause( p->pSatMain, pStart + Beg, pStart + End ); + if ( RetValue == 0 ) + { + printf( "Error: Solver is UNSAT after adding assumption clauses.\n" ); + return -1; + } + Beg = End; + } + // increment literals + for ( i = 0; i < Vec_IntSize(p->vLits); i++ ) + p->vLits->pArray[i] += nLitsTot; + } + + // simplify the solver + if ( p->pSatMain->qtail != p->pSatMain->qhead ) + { + RetValue = sat_solver_simplify(p->pSatMain); + assert( RetValue != 0 ); + assert( p->pSatMain->qtail == p->pSatMain->qhead ); + } + + // check if the property holds + if ( p->fTarget ) + { + if ( Fra_ClausRunSat0( p ) ) + { + if ( p->fVerbose ) + printf( " Property holds. " ); + } + else + { + if ( p->fVerbose ) + printf( " Property fails. " ); + // return -2; + p->fFail = 1; + } + } + +/* + // add the property for the first K frames + for ( i = 0; i < p->nFrames; i++ ) + { + Aig_Obj_t * pObj; + int Lits[2]; + // set the output literals + pObj = Aig_ManPo(p->pAig, 0); + Lits[0] = i * nLitsTot + toLitCond( p->pCnf->pVarNums[pObj->Id], 1 ); + // add the clause + RetValue = sat_solver_addclause( p->pSatMain, Lits, Lits + 1 ); +// assert( RetValue == 1 ); + if ( RetValue == 0 ) + { + printf( "Error: Solver is UNSAT after adding property for the first K frames.\n" ); + return -1; + } + } +*/ + + // simplify the solver + if ( p->pSatMain->qtail != p->pSatMain->qhead ) + { + RetValue = sat_solver_simplify(p->pSatMain); + assert( RetValue != 0 ); + assert( p->pSatMain->qtail == p->pSatMain->qhead ); + } + + + // check the clause in the last timeframe + Beg = 0; + Counter = 0; + Vec_IntForEachEntry( p->vClauses, End, i ) + { + if ( Vec_IntEntry( p->vCosts, i ) == -1 ) + { + Beg = End; + continue; + } + assert( Vec_IntEntry( p->vCosts, i ) > 0 ); + assert( End - Beg <= p->nLutSize ); + + if ( Fra_ClausSimInfoCheck(p, pStart + Beg, End - Beg) ) + { + fFlag = 1; +// printf( "s-" ); + + Beg = End; + Vec_IntWriteEntry( p->vCosts, i, -1 ); + Counter++; + continue; + } + else + { + fFlag = 0; +// printf( "s?" ); + } + + for ( k = Beg; k < End; k++ ) + pStart[k] = lit_neg( pStart[k] ); + RetValue = sat_solver_solve( p->pSatMain, pStart + Beg, pStart + End, (ABC_INT64_T)p->nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); + for ( k = Beg; k < End; k++ ) + pStart[k] = lit_neg( pStart[k] ); + + // the problem is not solved + if ( RetValue != l_False ) + { +// printf( "S- " ); +// Fra_ClausSimInfoRecord( p, (int*)p->pSatMain->model.ptr + p->nFrames * p->pCnf->nVars ); + Fra_ClausSimInfoRecord( p, (int*)p->pSatMain->model + p->nFrames * p->pCnf->nVars ); +// RetValue = Fra_ClausSimInfoCheck(p, pStart + Beg, End - Beg); +// assert( RetValue ); + + Beg = End; + Vec_IntWriteEntry( p->vCosts, i, -1 ); + Counter++; + continue; + } +// printf( "S+ " ); +// assert( !fFlag ); + +/* + // add the clause + RetValue = sat_solver_addclause( p->pSatMain, pStart + Beg, pStart + End ); +// assert( RetValue == 1 ); + if ( RetValue == 0 ) + { + printf( "Error: Solver is UNSAT after adding proved clauses.\n" ); + return -1; + } +*/ + Beg = End; + + // simplify the solver + if ( p->pSatMain->qtail != p->pSatMain->qhead ) + { + RetValue = sat_solver_simplify(p->pSatMain); + assert( RetValue != 0 ); + assert( p->pSatMain->qtail == p->pSatMain->qhead ); + } + } + + // return clauses back to normal + nLitsTot = p->nFrames * nLitsTot; + for ( i = 0; i < Vec_IntSize(p->vLits); i++ ) + p->vLits->pArray[i] -= nLitsTot; + +// if ( fFail ) +// return -2; + return Counter; +} + + + +/**Function************************************************************* + + Synopsis [Converts AIG into the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Clu_Man_t * Fra_ClausAlloc( Aig_Man_t * pAig, int nFrames, int nPref, int nClausesMax, int nLutSize, int nLevels, int nCutsMax, int nBatches, int fStepUp, int fTarget, int fVerbose, int fVeryVerbose ) +{ + Clu_Man_t * p; + p = ABC_ALLOC( Clu_Man_t, 1 ); + memset( p, 0, sizeof(Clu_Man_t) ); + p->pAig = pAig; + p->nFrames = nFrames; + p->nPref = nPref; + p->nClausesMax = nClausesMax; + p->nLutSize = nLutSize; + p->nLevels = nLevels; + p->nCutsMax = nCutsMax; + p->nBatches = nBatches; + p->fStepUp = fStepUp; + p->fTarget = fTarget; + p->fVerbose = fVerbose; + p->fVeryVerbose = fVeryVerbose; + p->nSimWords = 512;//1024;//64; + p->nSimFrames = 32;//8;//32; + p->nSimWordsPref = p->nPref*p->nSimWords/p->nSimFrames; + + p->vLits = Vec_IntAlloc( 1<<14 ); + p->vClauses = Vec_IntAlloc( 1<<12 ); + p->vCosts = Vec_IntAlloc( 1<<12 ); + + p->vLitsProven = Vec_IntAlloc( 1<<14 ); + p->vClausesProven= Vec_IntAlloc( 1<<12 ); + + p->nCexesAlloc = 1024; + p->vCexes = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p->pAig)+1, p->nCexesAlloc/32 ); + Vec_PtrCleanSimInfo( p->vCexes, 0, p->nCexesAlloc/32 ); + return p; +} + +/**Function************************************************************* + + Synopsis [Converts AIG into the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fra_ClausFree( Clu_Man_t * p ) +{ + if ( p->vCexes ) Vec_PtrFree( p->vCexes ); + if ( p->vLits ) Vec_IntFree( p->vLits ); + if ( p->vClauses ) Vec_IntFree( p->vClauses ); + if ( p->vLitsProven ) Vec_IntFree( p->vLitsProven ); + if ( p->vClausesProven ) Vec_IntFree( p->vClausesProven ); + if ( p->vCosts ) Vec_IntFree( p->vCosts ); + if ( p->pCnf ) Cnf_DataFree( p->pCnf ); + if ( p->pSatMain ) sat_solver_delete( p->pSatMain ); + if ( p->pSatBmc ) sat_solver_delete( p->pSatBmc ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Converts AIG into the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fra_ClausAddToStorage( Clu_Man_t * p ) +{ + int * pStart; + int Beg, End, Counter, i, k; + Beg = 0; + Counter = 0; + pStart = Vec_IntArray( p->vLits ); + Vec_IntForEachEntry( p->vClauses, End, i ) + { + if ( Vec_IntEntry( p->vCosts, i ) == -1 ) + { + Beg = End; + continue; + } + assert( Vec_IntEntry( p->vCosts, i ) > 0 ); + assert( End - Beg <= p->nLutSize ); + for ( k = Beg; k < End; k++ ) + Vec_IntPush( p->vLitsProven, pStart[k] ); + Vec_IntPush( p->vClausesProven, Vec_IntSize(p->vLitsProven) ); + Beg = End; + Counter++; + + if ( i < p->nOneHots ) + p->nOneHotsProven++; + } + if ( p->fVerbose ) + printf( "Added to storage %d proved clauses (including %d one-hot clauses)\n", Counter, p->nOneHotsProven ); + + Vec_IntClear( p->vClauses ); + Vec_IntClear( p->vLits ); + Vec_IntClear( p->vCosts ); + p->nClauses = 0; + + p->fNothingNew = (int)(Counter == 0); +} + +/**Function************************************************************* + + Synopsis [Converts AIG into the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fra_ClausPrintIndClauses( Clu_Man_t * p ) +{ + int Counters[9] = {0}; + int * pStart; + int Beg, End, i; + Beg = 0; + pStart = Vec_IntArray( p->vLitsProven ); + Vec_IntForEachEntry( p->vClausesProven, End, i ) + { + if ( End - Beg >= 8 ) + Counters[8]++; + else + Counters[End - Beg]++; +//printf( "%d ", End-Beg ); + Beg = End; + } + printf( "SUMMARY: Total proved clauses = %d. ", Vec_IntSize(p->vClausesProven) ); + printf( "Clause per lit: " ); + for ( i = 0; i < 8; i++ ) + if ( Counters[i] ) + printf( "%d=%d ", i, Counters[i] ); + if ( Counters[8] ) + printf( ">7=%d ", Counters[8] ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Writes the clauses into an AIGER file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t * Fra_ClausGetLiteral( Clu_Man_t * p, int * pVar2Id, int Lit ) +{ + Aig_Obj_t * pLiteral; + int NodeId = pVar2Id[ lit_var(Lit) ]; + assert( NodeId >= 0 ); + pLiteral = (Aig_Obj_t *)Aig_ManObj( p->pAig, NodeId )->pData; + return Aig_NotCond( pLiteral, lit_sign(Lit) ); +} + +/**Function************************************************************* + + Synopsis [Writes the clauses into an AIGER file.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fra_ClausWriteIndClauses( Clu_Man_t * p ) +{ + extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact ); + Aig_Man_t * pNew; + Aig_Obj_t * pClause, * pLiteral; + char * pName; + int * pStart, * pVar2Id; + int Beg, End, i, k; + // create mapping from SAT vars to node IDs + pVar2Id = ABC_ALLOC( int, p->pCnf->nVars ); + memset( pVar2Id, 0xFF, sizeof(int) * p->pCnf->nVars ); + for ( i = 0; i < Aig_ManObjNumMax(p->pAig); i++ ) + if ( p->pCnf->pVarNums[i] >= 0 ) + { + assert( p->pCnf->pVarNums[i] < p->pCnf->nVars ); + pVar2Id[ p->pCnf->pVarNums[i] ] = i; + } + // start the manager + pNew = Aig_ManDupWithoutPos( p->pAig ); + // add the clauses + Beg = 0; + pStart = Vec_IntArray( p->vLitsProven ); + Vec_IntForEachEntry( p->vClausesProven, End, i ) + { + pClause = Fra_ClausGetLiteral( p, pVar2Id, pStart[Beg] ); + for ( k = Beg + 1; k < End; k++ ) + { + pLiteral = Fra_ClausGetLiteral( p, pVar2Id, pStart[k] ); + pClause = Aig_Or( pNew, pClause, pLiteral ); + } + Aig_ObjCreatePo( pNew, pClause ); + Beg = End; + } + ABC_FREE( pVar2Id ); + Aig_ManCleanup( pNew ); + pName = Ioa_FileNameGenericAppend( p->pAig->pName, "_care.aig" ); + printf( "Care one-hotness clauses will be written into file \"%s\".\n", pName ); + Ioa_WriteAiger( pNew, pName, 0, 1 ); + Aig_ManStop( pNew ); +} + +/**Function************************************************************* + + Synopsis [Checks if the clause holds using the given simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fra_ClausEstimateCoverageOne( Fra_Sml_t * pSim, int * pLits, int nLits, int * pVar2Id, unsigned * pResult ) +{ + unsigned * pSims[16]; + int iVar, i, w; + for ( i = 0; i < nLits; i++ ) + { + iVar = lit_var(pLits[i]); + pSims[i] = Fra_ObjSim( pSim, pVar2Id[iVar] ); + } + for ( w = 0; w < pSim->nWordsTotal; w++ ) + { + pResult[w] = ~(unsigned)0; + for ( i = 0; i < nLits; i++ ) + pResult[w] &= (lit_sign(pLits[i])? pSims[i][w] : ~pSims[i][w]); + } +} + +/**Function************************************************************* + + Synopsis [Estimates the coverage of state space by clauses.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fra_ClausEstimateCoverage( Clu_Man_t * p ) +{ + int nCombSimWords = (1<<11); + Fra_Sml_t * pComb; + unsigned * pResultTot, * pResultOne; + int nCovered, Beg, End, i, w; + int * pStart, * pVar2Id; + int clk = clock(); + // simulate the circuit with nCombSimWords * 32 = 64K patterns +// srand( 0xAABBAABB ); + Aig_ManRandom(1); + pComb = Fra_SmlSimulateComb( p->pAig, nCombSimWords ); + // create mapping from SAT vars to node IDs + pVar2Id = ABC_ALLOC( int, p->pCnf->nVars ); + memset( pVar2Id, 0, sizeof(int) * p->pCnf->nVars ); + for ( i = 0; i < Aig_ManObjNumMax(p->pAig); i++ ) + if ( p->pCnf->pVarNums[i] >= 0 ) + { + assert( p->pCnf->pVarNums[i] < p->pCnf->nVars ); + pVar2Id[ p->pCnf->pVarNums[i] ] = i; + } + // get storage for one assignment and all assignments + assert( Aig_ManPoNum(p->pAig) > 2 ); + pResultOne = Fra_ObjSim( pComb, Aig_ManPo(p->pAig, 0)->Id ); + pResultTot = Fra_ObjSim( pComb, Aig_ManPo(p->pAig, 1)->Id ); + // start the OR of don't-cares + for ( w = 0; w < nCombSimWords; w++ ) + pResultTot[w] = 0; + // check clauses + Beg = 0; + pStart = Vec_IntArray( p->vLitsProven ); + Vec_IntForEachEntry( p->vClausesProven, End, i ) + { + Fra_ClausEstimateCoverageOne( pComb, pStart + Beg, End-Beg, pVar2Id, pResultOne ); + Beg = End; + for ( w = 0; w < nCombSimWords; w++ ) + pResultTot[w] |= pResultOne[w]; + } + // count the total number of patterns contained in the don't-care + nCovered = 0; + for ( w = 0; w < nCombSimWords; w++ ) + nCovered += Aig_WordCountOnes( pResultTot[w] ); + Fra_SmlStop( pComb ); + ABC_FREE( pVar2Id ); + // print the result + printf( "Care states ratio = %f. ", 1.0 * (nCombSimWords * 32 - nCovered) / (nCombSimWords * 32) ); + printf( "(%d out of %d patterns) ", nCombSimWords * 32 - nCovered, nCombSimWords * 32 ); + ABC_PRT( "Time", clock() - clk ); +} + + +/**Function************************************************************* + + Synopsis [Converts AIG into the SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Fra_Claus( Aig_Man_t * pAig, int nFrames, int nPref, int nClausesMax, int nLutSize, int nLevels, int nCutsMax, int nBatches, int fStepUp, int fBmc, int fRefs, int fTarget, int fVerbose, int fVeryVerbose ) +{ + Clu_Man_t * p; + int clk, clkTotal = clock(), clkInd; + int b, Iter, Counter, nPrefOld; + int nClausesBeg = 0; + + // create the manager + p = Fra_ClausAlloc( pAig, nFrames, nPref, nClausesMax, nLutSize, nLevels, nCutsMax, nBatches, fStepUp, fTarget, fVerbose, fVeryVerbose ); +if ( p->fVerbose ) +{ + printf( "PARAMETERS: Frames = %d. Pref = %d. Clauses max = %d. Cut size = %d.\n", nFrames, nPref, nClausesMax, nLutSize ); + printf( "Level max = %d. Cuts max = %d. Batches = %d. Increment cut size = %s.\n", nLevels, nCutsMax, nBatches, fStepUp? "yes":"no" ); +//ABC_PRT( "Sim-seq", clock() - clk ); +} + + assert( !p->fTarget || Aig_ManPoNum(pAig) - Aig_ManRegNum(pAig) == 1 ); + +clk = clock(); + // derive CNF +// if ( p->fTarget ) +// p->pAig->nRegs++; + p->pCnf = Cnf_DeriveSimple( p->pAig, Aig_ManPoNum(p->pAig) ); +// if ( p->fTarget ) +// p->pAig->nRegs--; +if ( fVerbose ) +{ +//ABC_PRT( "CNF ", clock() - clk ); +} + + // check BMC +clk = clock(); + p->pSatBmc = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, p->nPref + p->nFrames, 1 ); + if ( p->pSatBmc == NULL ) + { + printf( "Error: BMC solver is unsat.\n" ); + Fra_ClausFree( p ); + return 1; + } + if ( p->fTarget && !Fra_ClausRunBmc( p ) ) + { + printf( "Problem fails the base case after %d frame expansion.\n", p->nPref + p->nFrames ); + Fra_ClausFree( p ); + return 1; + } +if ( fVerbose ) +{ +//ABC_PRT( "SAT-bmc", clock() - clk ); +} + + // start the SAT solver +clk = clock(); + p->pSatMain = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, p->nFrames+1, 0 ); + if ( p->pSatMain == NULL ) + { + printf( "Error: Main solver is unsat.\n" ); + Fra_ClausFree( p ); + return 1; + } + + + for ( b = 0; b < p->nBatches; b++ ) + { +// if ( fVerbose ) + printf( "*** BATCH %d: ", b+1 ); + if ( b && p->nLutSize < 12 && (!p->fFiltering || p->fNothingNew || p->fStepUp) ) + p->nLutSize++; + printf( "Using %d-cuts.\n", p->nLutSize ); + + // try solving without additional clauses + if ( p->fTarget && Fra_ClausRunSat( p ) ) + { + printf( "Problem is inductive without strengthening.\n" ); + Fra_ClausFree( p ); + return 1; + } + if ( fVerbose ) + { +// ABC_PRT( "SAT-ind", clock() - clk ); + } + + // collect the candidate inductive clauses using 4-cuts + clk = clock(); + nPrefOld = p->nPref; p->nPref = 0; p->nSimWordsPref = 0; + // Fra_ClausProcessClauses( p, fRefs ); + Fra_ClausProcessClauses2( p, fRefs ); + p->nPref = nPrefOld; + p->nSimWordsPref = p->nPref*p->nSimWords/p->nSimFrames; + nClausesBeg = p->nClauses; + + //ABC_PRT( "Clauses", clock() - clk ); + + + // check clauses using BMC + if ( fBmc ) + { + clk = clock(); + Counter = Fra_ClausBmcClauses( p ); + p->nClauses -= Counter; + if ( fVerbose ) + { + printf( "BMC disproved %d clauses. ", Counter ); + ABC_PRT( "Time", clock() - clk ); + } + } + + + // prove clauses inductively + clkInd = clk = clock(); + Counter = 1; + for ( Iter = 0; Counter > 0; Iter++ ) + { + if ( fVerbose ) + printf( "Iter %3d : Begin = %5d. ", Iter, p->nClauses ); + Counter = Fra_ClausInductiveClauses( p ); + if ( Counter > 0 ) + p->nClauses -= Counter; + if ( fVerbose ) + { + printf( "End = %5d. Exs = %5d. ", p->nClauses, p->nCexes ); + // printf( "\n" ); + ABC_PRT( "Time", clock() - clk ); + } + clk = clock(); + } + // add proved clauses to storage + Fra_ClausAddToStorage( p ); + // report the results + if ( p->fTarget ) + { + if ( Counter == -1 ) + printf( "Fra_Claus(): Internal error. " ); + else if ( p->fFail ) + printf( "Property FAILS during refinement. " ); + else + printf( "Property HOLDS inductively after strengthening. " ); + ABC_PRT( "Time ", clock() - clkTotal ); + if ( !p->fFail ) + break; + } + else + { + printf( "Finished proving inductive clauses. " ); + ABC_PRT( "Time ", clock() - clkTotal ); + } + } + + // 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 ); + } + + if ( !p->fTarget ) + { + Fra_ClausWriteIndClauses( p ); + } +/* + // print the statistic into a file + { + FILE * pTable; + assert( p->nBatches == 1 ); + pTable = fopen( "stats.txt", "a+" ); + fprintf( pTable, "%s ", pAig->pName ); + fprintf( pTable, "%d ", Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig) ); + fprintf( pTable, "%d ", Aig_ManPoNum(pAig)-Aig_ManRegNum(pAig) ); + fprintf( pTable, "%d ", Aig_ManRegNum(pAig) ); + fprintf( pTable, "%d ", Aig_ManNodeNum(pAig) ); + fprintf( pTable, "%d ", p->nCuts ); + fprintf( pTable, "%d ", nClausesBeg ); + fprintf( pTable, "%d ", p->nClauses ); + fprintf( pTable, "%d ", Iter ); + fprintf( pTable, "%.2f ", (float)(clkInd-clkTotal)/(float)(CLOCKS_PER_SEC) ); + fprintf( pTable, "%.2f ", (float)(clock()-clkInd)/(float)(CLOCKS_PER_SEC) ); + fprintf( pTable, "%.2f ", (float)(clock()-clkTotal)/(float)(CLOCKS_PER_SEC) ); + fprintf( pTable, "\n" ); + fclose( pTable ); + } +*/ + // clean the manager + Fra_ClausFree( p ); + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + |