sfmSat.c 7.43 KB
Newer Older
Alan Mishchenko committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/**CFile****************************************************************

  FileName    [sfmSat.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [SAT-based optimization using internal don't-cares.]

  Synopsis    [SAT-based procedures.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 20, 2005.]

  Revision    [$Id: sfmSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]

***********************************************************************/

#include "sfmInt.h"

ABC_NAMESPACE_IMPL_START


////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

Alan Mishchenko committed
30 31 32 33 34 35 36 37 38
static word s_Truths6[6] = {
    ABC_CONST(0xAAAAAAAAAAAAAAAA),
    ABC_CONST(0xCCCCCCCCCCCCCCCC),
    ABC_CONST(0xF0F0F0F0F0F0F0F0),
    ABC_CONST(0xFF00FF00FF00FF00),
    ABC_CONST(0xFFFF0000FFFF0000),
    ABC_CONST(0xFFFFFFFF00000000)
};

Alan Mishchenko committed
39 40 41 42 43 44
////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

Alan Mishchenko committed
45 46 47 48 49 50 51 52 53
  Synopsis    [Converts a window into a SAT solver.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
54
void Sfm_NtkWindowToSolver( Sfm_Ntk_t * p )
Alan Mishchenko committed
55 56
{
    Vec_Int_t * vClause;
Alan Mishchenko committed
57
    int RetValue, iNode = -1, iFanin, i, k;
Alan Mishchenko committed
58
    clock_t clk = clock();
Alan Mishchenko committed
59 60 61
//    if ( p->pSat )
//        printf( "%d  ", p->pSat->stats.learnts );
    sat_solver_restart( p->pSat );
Alan Mishchenko committed
62
    sat_solver_setnvars( p->pSat, 1 + Vec_IntSize(p->vDivs) + 2 * Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots) + 50 );
Alan Mishchenko committed
63
    // create SAT variables
Alan Mishchenko committed
64
    Sfm_NtkCleanVars( p );
Alan Mishchenko committed
65
    p->nSatVars = 1;
Alan Mishchenko committed
66
    Vec_IntForEachEntry( p->vOrder, iNode, i )
Alan Mishchenko committed
67
        Sfm_ObjSetSatVar( p, iNode, p->nSatVars++ );
Alan Mishchenko committed
68
    // collect divisor variables
Alan Mishchenko committed
69 70 71
    Vec_IntClear( p->vDivVars );
    Vec_IntForEachEntry( p->vDivs, iNode, i )
        Vec_IntPush( p->vDivVars, Sfm_ObjSatVar(p, iNode) );
Alan Mishchenko committed
72 73
    // add CNF clauses for the TFI
    Vec_IntForEachEntry( p->vOrder, iNode, i )
Alan Mishchenko committed
74
    {
Alan Mishchenko committed
75 76
        if ( Sfm_ObjIsPi(p, iNode) )
            continue;
Alan Mishchenko committed
77 78 79 80 81 82 83 84 85
        // collect fanin variables
        Vec_IntClear( p->vFaninMap );
        Sfm_ObjForEachFanin( p, iNode, iFanin, k )
            Vec_IntPush( p->vFaninMap, Sfm_ObjSatVar(p, iFanin) );
        Vec_IntPush( p->vFaninMap, Sfm_ObjSatVar(p, iNode) );
        // generate CNF 
        Sfm_TranslateCnf( p->vClauses, (Vec_Str_t *)Vec_WecEntry(p->vCnfs, iNode), p->vFaninMap );
        // add clauses
        Vec_WecForEachLevel( p->vClauses, vClause, k )
Alan Mishchenko committed
86
        {
Alan Mishchenko committed
87 88
            if ( Vec_IntSize(vClause) == 0 )
                break;
Alan Mishchenko committed
89
            RetValue = sat_solver_addclause( p->pSat, Vec_IntArray(vClause), Vec_IntArray(vClause) + Vec_IntSize(vClause) );
Alan Mishchenko committed
90
            assert( RetValue );
Alan Mishchenko committed
91 92 93
        }
    }
    // finalize
Alan Mishchenko committed
94
    RetValue = sat_solver_simplify( p->pSat );
Alan Mishchenko committed
95
    assert( RetValue );
Alan Mishchenko committed
96
    p->timeCnf += clock() - clk;
Alan Mishchenko committed
97
} 
Alan Mishchenko committed
98 99 100

/**Function*************************************************************

Alan Mishchenko committed
101
  Synopsis    [Takes SAT solver and returns interpolant.]
Alan Mishchenko committed
102

Alan Mishchenko committed
103
  Description [If interpolant does not exist, records difference variables.]
Alan Mishchenko committed
104 105 106 107 108 109
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
110
word Sfm_ComputeInterpolant( Sfm_Ntk_t * p )
Alan Mishchenko committed
111
{
Alan Mishchenko committed
112
    word * pSign, uCube, uTruth = 0;
Alan Mishchenko committed
113
    int status, i, Div, iVar, nFinal, * pFinal, nIter = 0;
Alan Mishchenko committed
114 115 116 117
    int pLits[2], nVars = sat_solver_nvars( p->pSat );
    sat_solver_setnvars( p->pSat, nVars + 1 );
    pLits[0] = Abc_Var2Lit( Sfm_ObjSatVar(p, Vec_IntEntryLast(p->vNodes)), 0 ); // F = 1
    pLits[1] = Abc_Var2Lit( nVars, 0 ); // iNewLit
Alan Mishchenko committed
118 119 120
    while ( 1 ) 
    {
        // find onset minterm
Alan Mishchenko committed
121
        p->nSatCalls++;
Alan Mishchenko committed
122
        status = sat_solver_solve( p->pSat, pLits, pLits + 2, p->pPars->nBTLimit, 0, 0, 0 );
Alan Mishchenko committed
123 124 125 126 127
        if ( status == l_Undef )
            return SFM_SAT_UNDEC;
        if ( status == l_False )
            return uTruth;
        assert( status == l_True );
Alan Mishchenko committed
128 129 130 131
        // remember variable values
        Vec_IntClear( p->vValues );
        Vec_IntForEachEntry( p->vDivVars, iVar, i )
            Vec_IntPush( p->vValues, sat_solver_var_value(p->pSat, iVar) );
Alan Mishchenko committed
132 133
        // collect divisor literals
        Vec_IntClear( p->vLits );
Alan Mishchenko committed
134
        Vec_IntPush( p->vLits, Abc_LitNot(pLits[0]) ); // F = 0
Alan Mishchenko committed
135
        Vec_IntForEachEntry( p->vDivIds, Div, i )
Alan Mishchenko committed
136
            Vec_IntPush( p->vLits, sat_solver_var_literal(p->pSat, Div) );
Alan Mishchenko committed
137
        // check against offset
Alan Mishchenko committed
138
        p->nSatCalls++;
Alan Mishchenko committed
139
        status = sat_solver_solve( p->pSat, Vec_IntArray(p->vLits), Vec_IntArray(p->vLits) + Vec_IntSize(p->vLits), p->pPars->nBTLimit, 0, 0, 0 );
Alan Mishchenko committed
140 141 142
        if ( status == l_Undef )
            return SFM_SAT_UNDEC;
        if ( status == l_True )
Alan Mishchenko committed
143
            break;
Alan Mishchenko committed
144 145
        assert( status == l_False );
        // compute cube and add clause
Alan Mishchenko committed
146
        nFinal = sat_solver_final( p->pSat, &pFinal );
Alan Mishchenko committed
147
        uCube = ~(word)0;
Alan Mishchenko committed
148
        Vec_IntClear( p->vLits );
Alan Mishchenko committed
149
        Vec_IntPush( p->vLits, Abc_LitNot(pLits[1]) ); // NOT(iNewLit)
Alan Mishchenko committed
150 151
        for ( i = 0; i < nFinal; i++ )
        {
Alan Mishchenko committed
152 153
            if ( pFinal[i] == pLits[0] )
                continue;
Alan Mishchenko committed
154 155
            Vec_IntPush( p->vLits, pFinal[i] );
            iVar = Vec_IntFind( p->vDivIds, Abc_Lit2Var(pFinal[i]) );   assert( iVar >= 0 );
Alan Mishchenko committed
156 157 158
            uCube &= Abc_LitIsCompl(pFinal[i]) ? s_Truths6[iVar] : ~s_Truths6[iVar];
        }
        uTruth |= uCube;
Alan Mishchenko committed
159
        status = sat_solver_addclause( p->pSat, Vec_IntArray(p->vLits), Vec_IntArray(p->vLits) + Vec_IntSize(p->vLits) );
Alan Mishchenko committed
160
        assert( status );
Alan Mishchenko committed
161
        nIter++;
Alan Mishchenko committed
162
    }
Alan Mishchenko committed
163 164 165
    assert( status == l_True );
    // store the counter-example
    Vec_IntForEachEntry( p->vDivVars, iVar, i )
Alan Mishchenko committed
166
        if ( Vec_IntEntry(p->vValues, i) ^ sat_solver_var_value(p->pSat, iVar) ) // insert 1
Alan Mishchenko committed
167 168 169 170 171 172 173
        {
            pSign = Vec_WrdEntryP( p->vDivCexes, i );
            assert( !Abc_InfoHasBit( (unsigned *)pSign, p->nCexes) );
            Abc_InfoXorBit( (unsigned *)pSign, p->nCexes );
        }
    p->nCexes++;
    return SFM_SAT_SAT;
Alan Mishchenko committed
174 175
}

Alan Mishchenko committed
176 177 178 179 180 181 182 183 184 185 186 187 188 189
/**Function*************************************************************

  Synopsis    [Checks resubstitution.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Sfm_ComputeInterpolantCheck( Sfm_Ntk_t * p )
{
    int iNode = 3;
Alan Mishchenko committed
190 191
    int iDiv0 = 6;
    int iDiv1 = 7;
Alan Mishchenko committed
192 193 194 195
    word uTruth;
//    int i;
//    Sfm_NtkForEachNode( p, i )
    {
Alan Mishchenko committed
196 197
        Sfm_NtkCreateWindow( p, iNode, 1 );
        Sfm_NtkWindowToSolver( p );
Alan Mishchenko committed
198 199 200 201 202 203

        // collect SAT variables of divisors
        Vec_IntClear( p->vDivIds );
        Vec_IntPush( p->vDivIds, Sfm_ObjSatVar(p, iDiv0) );
        Vec_IntPush( p->vDivIds, Sfm_ObjSatVar(p, iDiv1) );

Alan Mishchenko committed
204
        uTruth = Sfm_ComputeInterpolant( p );
Alan Mishchenko committed
205 206 207 208 209 210 211 212 213 214

        if ( uTruth == SFM_SAT_SAT )
            printf( "The problem is SAT.\n" );
        else if ( uTruth == SFM_SAT_UNDEC )
            printf( "The problem is UNDEC.\n" );
        else
            Kit_DsdPrintFromTruth( (unsigned *)&uTruth, 2 ); printf( "\n" );
    }
}

Alan Mishchenko committed
215 216 217 218 219 220 221
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END