summaryrefslogtreecommitdiffstats
path: root/src/opt/sbd/sbdWin.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2016-11-28 15:50:15 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2016-11-28 15:50:15 -0800
commit5d61e53c7a09d544e4cdbb74e31fc919680f0e4e (patch)
tree0969f45954dde311221d46d6b8f52ba098ad3c37 /src/opt/sbd/sbdWin.c
parent53adc97675511f41fd9c40c31dcb9b3506f75daf (diff)
downloadabc-5d61e53c7a09d544e4cdbb74e31fc919680f0e4e.tar.gz
abc-5d61e53c7a09d544e4cdbb74e31fc919680f0e4e.tar.bz2
abc-5d61e53c7a09d544e4cdbb74e31fc919680f0e4e.zip
New SAT-based optimization package.
Diffstat (limited to 'src/opt/sbd/sbdWin.c')
-rw-r--r--src/opt/sbd/sbdWin.c151
1 files changed, 149 insertions, 2 deletions
diff --git a/src/opt/sbd/sbdWin.c b/src/opt/sbd/sbdWin.c
index e8702f7d..8f320038 100644
--- a/src/opt/sbd/sbdWin.c
+++ b/src/opt/sbd/sbdWin.c
@@ -33,15 +33,162 @@ ABC_NAMESPACE_IMPL_START
/**Function*************************************************************
- Synopsis []
+ Synopsis [Constructs SAT solver for the window.]
+
+ Description [The window for the pivot node (Pivot) is represented as
+ a DFS ordered array of objects (vWinObjs) whose indexed in the array
+ (which will be used as SAT variables) are given in array vObj2Var.
+ The TFO nodes are listed as the last ones in vWinObjs. The root nodes
+ are labeled with Abc_LitIsCompl() in vTfo and also given in vRoots.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+sat_solver * Sbd_ManSatSolver( sat_solver * pSat, Gia_Man_t * p, int Pivot, Vec_Int_t * vWinObjs, Vec_Int_t * vObj2Var, Vec_Int_t * vTfo, Vec_Int_t * vRoots )
+{
+ Gia_Obj_t * pObj;
+ int i, iObj, Fan0, Fan1, Node, fCompl0, fCompl1, RetValue;
+ int PivotVar = Vec_IntEntry(vObj2Var, Pivot);
+ // create SAT solver
+ if ( pSat == NULL )
+ pSat = sat_solver_new();
+ else
+ sat_solver_restart( pSat );
+ sat_solver_setnvars( pSat, Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo) + Vec_IntSize(vRoots) + 32 );
+ // add clauses for all nodes
+ Vec_IntForEachEntry( vWinObjs, iObj, i )
+ {
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ continue;
+ assert( Gia_ObjIsAnd(pObj) );
+ Node = Vec_IntEntry( vObj2Var, iObj );
+ Fan0 = Vec_IntEntry( vObj2Var, Gia_ObjFaninId0(pObj, iObj) );
+ Fan1 = Vec_IntEntry( vObj2Var, Gia_ObjFaninId1(pObj, iObj) );
+ fCompl0 = Gia_ObjFaninC0(pObj);
+ fCompl1 = Gia_ObjFaninC1(pObj);
+ if ( Gia_ObjIsXor(pObj) )
+ sat_solver_add_xor( pSat, Node, Fan0, Fan1, fCompl0 ^ fCompl1 );
+ else
+ sat_solver_add_and( pSat, Node, Fan0, Fan1, fCompl0, fCompl1, 0 );
+ }
+ // add second clauses for the TFO
+ Vec_IntForEachEntryStart( vWinObjs, iObj, i, Vec_IntSize(vWinObjs) - Vec_IntSize(vTfo) )
+ {
+ pObj = Gia_ManObj( p, iObj );
+ assert( Gia_ObjIsAnd(pObj) );
+ Node = Vec_IntEntry( vObj2Var, iObj ) + Vec_IntSize(vTfo);
+ Fan0 = Vec_IntEntry( vObj2Var, Gia_ObjFaninId0(pObj, iObj) );
+ Fan1 = Vec_IntEntry( vObj2Var, Gia_ObjFaninId1(pObj, iObj) );
+ Fan0 = Fan0 <= PivotVar ? Fan0 : Fan0 + Vec_IntSize(vTfo);
+ Fan1 = Fan1 <= PivotVar ? Fan1 : Fan1 + Vec_IntSize(vTfo);
+ fCompl0 = Gia_ObjFaninC0(pObj) ^ (Fan0 == PivotVar);
+ fCompl1 = Gia_ObjFaninC1(pObj) ^ (Fan1 == PivotVar);
+ if ( Gia_ObjIsXor(pObj) )
+ sat_solver_add_xor( pSat, Node, Fan0, Fan1, fCompl0 ^ fCompl1 );
+ else
+ sat_solver_add_and( pSat, Node, Fan0, Fan1, fCompl0, fCompl1, 0 );
+ }
+ if ( Vec_IntSize(vRoots) > 0 )
+ {
+ // create XOR clauses for the roots
+ int nVars = Vec_IntSize(vWinObjs) + Vec_IntSize(vTfo);
+ Vec_Int_t * vFaninVars = Vec_IntAlloc( Vec_IntSize(vRoots) );
+ Vec_IntForEachEntry( vRoots, iObj, i )
+ {
+ Vec_IntPush( vFaninVars, Abc_Var2Lit(nVars, 0) );
+ Node = Vec_IntEntry( vObj2Var, iObj );
+ sat_solver_add_xor( pSat, Node, Node + Vec_IntSize(vTfo), nVars++, 0 );
+ }
+ // make OR clause for the last nRoots variables
+ RetValue = sat_solver_addclause( pSat, Vec_IntArray(vFaninVars), Vec_IntLimit(vFaninVars) );
+ Vec_IntFree( vFaninVars );
+ if ( RetValue == 0 )
+ return 0;
+ assert( sat_solver_nvars(pSat) == nVars + 32 );
+ }
+ // finalize
+ RetValue = sat_solver_simplify( pSat );
+ if ( RetValue == 0 )
+ {
+ sat_solver_delete( pSat );
+ return NULL;
+ }
+ return pSat;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Solves one SAT problem.]
- Description []
+ Description [Computes node function for PivotVar with fanins in vDivVars
+ using don't-care represented in the SAT solver. Uses array vValues to
+ return the values of the first Vec_IntSize(vValues) SAT variables in case
+ the implementation of the node with the given fanins does not exist.]
SideEffects []
SeeAlso []
***********************************************************************/
+word Sbd_ManSolve( sat_solver * pSat, int PivotVar, int FreeVar, Vec_Int_t * vDivVars, Vec_Int_t * vValues, Vec_Int_t * vTemp )
+{
+ int nBTLimit = 0;
+ word uCube, uTruth = 0;
+ int status, i, iVar, nFinal, * pFinal, pLits[2], nIter = 0;
+ pLits[0] = Abc_Var2Lit( PivotVar, 0 ); // F = 1
+ pLits[1] = Abc_Var2Lit( FreeVar, 0 ); // iNewLit
+ assert( Vec_IntSize(vValues) <= sat_solver_nvars(pSat) );
+ while ( 1 )
+ {
+ // find onset minterm
+ status = sat_solver_solve( pSat, pLits, pLits + 2, nBTLimit, 0, 0, 0 );
+ if ( status == l_Undef )
+ return SBD_SAT_UNDEC;
+ if ( status == l_False )
+ return uTruth;
+ assert( status == l_True );
+ // remember variable values
+ for ( i = 0; i < Vec_IntSize(vValues); i++ )
+ Vec_IntWriteEntry( vValues, i, sat_solver_var_value(pSat, i) );
+ // collect divisor literals
+ Vec_IntClear( vTemp );
+ Vec_IntPush( vTemp, Abc_LitNot(pLits[0]) ); // F = 0
+ Vec_IntForEachEntry( vDivVars, iVar, i )
+ Vec_IntPush( vTemp, sat_solver_var_literal(pSat, iVar) );
+ // check against offset
+ status = sat_solver_solve( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp), nBTLimit, 0, 0, 0 );
+ if ( status == l_Undef )
+ return SBD_SAT_UNDEC;
+ if ( status == l_True )
+ break;
+ assert( status == l_False );
+ // compute cube and add clause
+ nFinal = sat_solver_final( pSat, &pFinal );
+ uCube = ~(word)0;
+ Vec_IntClear( vTemp );
+ Vec_IntPush( vTemp, Abc_LitNot(pLits[1]) ); // NOT(iNewLit)
+ for ( i = 0; i < nFinal; i++ )
+ {
+ if ( pFinal[i] == pLits[0] )
+ continue;
+ Vec_IntPush( vTemp, pFinal[i] );
+ iVar = Vec_IntFind( vDivVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 );
+ uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar];
+ }
+ uTruth |= uCube;
+ status = sat_solver_addclause( pSat, Vec_IntArray(vTemp), Vec_IntArray(vTemp) + Vec_IntSize(vTemp) );
+ assert( status );
+ nIter++;
+ }
+ assert( status == l_True );
+ // store the counter-example
+ for ( i = 0; i < Vec_IntSize(vValues); i++ )
+ Vec_IntAddToEntry( vValues, i, 2*sat_solver_var_value(pSat, i) );
+ return SBD_SAT_SAT;
+}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///