simSymSat.c 6.96 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
/**CFile****************************************************************

  FileName    [simSymSat.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Network and node package.]

  Synopsis    [Satisfiability to determine two variable symmetries.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

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

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

21 22
#include "base/abc/abc.h"
#include "proof/fraig/fraig.h"
Alan Mishchenko committed
23 24
#include "sim.h"

25 26 27
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
28 29 30 31
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

Alan Mishchenko committed
32
static int Sim_SymmsSatProveOne( Sym_Man_t * p, int Out, int Var1, int Var2, unsigned * pPattern );
Alan Mishchenko committed
33 34

////////////////////////////////////////////////////////////////////////
Alan Mishchenko committed
35
///                     FUNCTION DEFINITIONS                         ///
Alan Mishchenko committed
36 37 38 39
////////////////////////////////////////////////////////////////////////

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

Alan Mishchenko committed
40
  Synopsis    [Tries to prove the remaining pairs using SAT.]
Alan Mishchenko committed
41

Alan Mishchenko committed
42 43 44
  Description [Continues to prove as long as it encounters symmetric pairs.
  Returns 1 if a non-symmetric pair is found (which gives a counter-example).
  Returns 0 if it finishes considering all pairs for all outputs.]
Alan Mishchenko committed
45 46 47 48 49 50
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
51
int Sim_SymmsGetPatternUsingSat( Sym_Man_t * p, unsigned * pPattern )
Alan Mishchenko committed
52
{
Alan Mishchenko committed
53 54 55 56
    Vec_Int_t * vSupport;
    Extra_BitMat_t * pMatSym, * pMatNonSym;
    int Index1, Index2, Index3, IndexU, IndexV;
    int v, u, i, k, b, out;
Alan Mishchenko committed
57

Alan Mishchenko committed
58 59
    // iterate through outputs
    for ( out = p->iOutput; out < p->nOutputs; out++ )
Alan Mishchenko committed
60
    {
61 62
        pMatSym    = (Extra_BitMat_t *)Vec_PtrEntry( p->vMatrSymms,    out );
        pMatNonSym = (Extra_BitMat_t *)Vec_PtrEntry( p->vMatrNonSymms, out );
Alan Mishchenko committed
63 64

        // go through the remaining variable pairs
65
        vSupport = Vec_VecEntryInt( p->vSupports, out );
Alan Mishchenko committed
66 67
        Vec_IntForEachEntry( vSupport, v, Index1 )
        Vec_IntForEachEntryStart( vSupport, u, Index2, Index1+1 )
Alan Mishchenko committed
68
        {
Alan Mishchenko committed
69 70 71
            if ( Extra_BitMatrixLookup1( pMatSym, v, u ) || Extra_BitMatrixLookup1( pMatNonSym, v, u ) )
                continue;
            p->nSatRuns++;
Alan Mishchenko committed
72

Alan Mishchenko committed
73 74 75 76
            // collect the support variables that are symmetric with u and v
            Vec_IntClear( p->vVarsU );
            Vec_IntClear( p->vVarsV );
            Vec_IntForEachEntry( vSupport, b, Index3 )
Alan Mishchenko committed
77
            {
Alan Mishchenko committed
78 79 80 81
                if ( Extra_BitMatrixLookup1( pMatSym, u, b ) )
                    Vec_IntPush( p->vVarsU, b );
                if ( Extra_BitMatrixLookup1( pMatSym, v, b ) )
                    Vec_IntPush( p->vVarsV, b );
Alan Mishchenko committed
82
            }
Alan Mishchenko committed
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112

            if ( Sim_SymmsSatProveOne( p, out, v, u, pPattern ) )
            { // update the symmetric variable info            
                p->nSatRunsUnsat++;
                Vec_IntForEachEntry( p->vVarsU, i, IndexU )
                Vec_IntForEachEntry( p->vVarsV, k, IndexV )
                {
                    Extra_BitMatrixInsert1( pMatSym,  i, k );  // Theorem 1
                    Extra_BitMatrixInsert2( pMatSym,  i, k );  // Theorem 1
                    Extra_BitMatrixOrTwo( pMatNonSym, i, k );  // Theorem 2
                }
            }
            else
            { // update the assymmetric variable info
                p->nSatRunsSat++;
                Vec_IntForEachEntry( p->vVarsU, i, IndexU )
                Vec_IntForEachEntry( p->vVarsV, k, IndexV )
                {
                    Extra_BitMatrixInsert1( pMatNonSym, i, k );   // Theorem 3
                    Extra_BitMatrixInsert2( pMatNonSym, i, k );   // Theorem 3
                }

                // remember the out
                p->iOutput = out;
                p->iVar1Old = p->iVar1;
                p->iVar2Old = p->iVar2;
                p->iVar1 = v;
                p->iVar2 = u;
                return 1;

Alan Mishchenko committed
113 114
            }
        }
Alan Mishchenko committed
115 116
        // make sure that the symmetry matrix contains only cliques
        assert( Extra_BitMatrixIsClique( pMatSym ) );
Alan Mishchenko committed
117 118
    }

Alan Mishchenko committed
119 120 121
    // mark that we finished all outputs
    p->iOutput = p->nOutputs;
    return 0;
Alan Mishchenko committed
122 123 124 125 126 127 128 129 130 131 132 133 134
}

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

  Synopsis    [Returns 1 if the variables are symmetric; 0 otherwise.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
135
int Sim_SymmsSatProveOne( Sym_Man_t * p, int Out, int Var1, int Var2, unsigned * pPattern )
Alan Mishchenko committed
136
{
Alan Mishchenko committed
137 138 139
    Fraig_Params_t Params;
    Fraig_Man_t * pMan;
    Abc_Ntk_t * pMiter;
140
    int RetValue, i;
141
    abctime clk;
Alan Mishchenko committed
142 143 144 145 146 147 148 149 150
    int * pModel;

    // get the miter for this problem
    pMiter = Abc_NtkMiterForCofactors( p->pNtk, Out, Var1, Var2 );
    // transform the miter into a fraig
    Fraig_ParamsSetDefault( &Params );
    Params.fInternal = 1;
    Params.nPatsRand = 512;
    Params.nPatsDyna = 512;
Alan Mishchenko committed
151
    Params.nSeconds = ABC_INFINITY;
Alan Mishchenko committed
152

153
clk = Abc_Clock();
154
    pMan = (Fraig_Man_t *)Abc_NtkToFraig( pMiter, &Params, 0, 0 ); 
155 156
p->timeFraig += Abc_Clock() - clk;
clk = Abc_Clock();
Alan Mishchenko committed
157
    Fraig_ManProveMiter( pMan );
158
p->timeSat += Abc_Clock() - clk;
Alan Mishchenko committed
159 160 161 162 163 164

    // analyze the result
    RetValue = Fraig_ManCheckMiter( pMan );
//    assert( RetValue >= 0 );
    // save the pattern
    if ( RetValue == 0 )
Alan Mishchenko committed
165
    {
Alan Mishchenko committed
166 167 168 169 170 171 172 173 174 175 176 177 178
        // get the pattern
        pModel = Fraig_ManReadModel( pMan );
        assert( pModel != NULL );
//printf( "Disproved by SAT: out = %d  pair = (%d, %d)\n", Out, Var1, Var2 );
        // transfer the model into the pattern
        for ( i = 0; i < p->nSimWords; i++ )
            pPattern[i] = 0;
        for ( i = 0; i < p->nInputs; i++ )
            if ( pModel[i] )
                Sim_SetBit( pPattern, i );
        // make sure these variables have the same value (1)
        Sim_SetBit( pPattern, Var1 );
        Sim_SetBit( pPattern, Var2 );
Alan Mishchenko committed
179
    }
Alan Mishchenko committed
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
    else if ( RetValue == -1 )
    {
        // this should never happen; if it happens, such is life
        // we are conservative and assume that there is no symmetry
//printf( "STRANGE THING: out = %d %s  pair = (%d %s, %d %s)\n", 
//                        Out, Abc_ObjName(Abc_NtkCo(p->pNtk,Out)), 
//                        Var1, Abc_ObjName(Abc_NtkCi(p->pNtk,Var1)), 
//                        Var2, Abc_ObjName(Abc_NtkCi(p->pNtk,Var2)) );
        memset( pPattern, 0, sizeof(unsigned) * p->nSimWords );
        RetValue = 0;
    }
    // delete the fraig manager
    Fraig_ManFree( pMan );
    // delete the miter
    Abc_NtkDelete( pMiter );
    return RetValue;
Alan Mishchenko committed
196 197 198 199 200 201 202 203
}


////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


204 205
ABC_NAMESPACE_IMPL_END