simSymSat.c 6.8 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
/**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 $]

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

#include "abc.h"
#include "sim.h"
Alan Mishchenko committed
23
#include "fraig.h"
Alan Mishchenko committed
24 25 26 27 28

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

Alan Mishchenko committed
29
static int Sim_SymmsSatProveOne( Sym_Man_t * p, int Out, int Var1, int Var2, unsigned * pPattern );
Alan Mishchenko committed
30 31

////////////////////////////////////////////////////////////////////////
Alan Mishchenko committed
32
///                     FUNCTION DEFINITIONS                         ///
Alan Mishchenko committed
33 34 35 36
////////////////////////////////////////////////////////////////////////

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

Alan Mishchenko committed
37
  Synopsis    [Tries to prove the remaining pairs using SAT.]
Alan Mishchenko committed
38

Alan Mishchenko committed
39 40 41
  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
42 43 44 45 46 47
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
48
int Sim_SymmsGetPatternUsingSat( Sym_Man_t * p, unsigned * pPattern )
Alan Mishchenko committed
49
{
Alan Mishchenko committed
50 51 52 53
    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
54

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

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

Alan Mishchenko committed
70 71 72 73
            // 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
74
            {
Alan Mishchenko committed
75 76 77 78
                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
79
            }
Alan Mishchenko committed
80 81 82 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

            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
110 111
            }
        }
Alan Mishchenko committed
112 113
        // make sure that the symmetry matrix contains only cliques
        assert( Extra_BitMatrixIsClique( pMatSym ) );
Alan Mishchenko committed
114 115
    }

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

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

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

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
132
int Sim_SymmsSatProveOne( Sym_Man_t * p, int Out, int Var1, int Var2, unsigned * pPattern )
Alan Mishchenko committed
133
{
Alan Mishchenko committed
134 135 136 137 138 139 140 141 142 143 144 145 146
    Fraig_Params_t Params;
    Fraig_Man_t * pMan;
    Abc_Ntk_t * pMiter;
    int RetValue, i, clk;
    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
147
    Params.nSeconds = ABC_INFINITY;
Alan Mishchenko committed
148 149

clk = clock();
Alan Mishchenko committed
150
    pMan = Abc_NtkToFraig( pMiter, &Params, 0, 0 ); 
Alan Mishchenko committed
151 152 153 154 155 156 157 158 159 160
p->timeFraig += clock() - clk;
clk = clock();
    Fraig_ManProveMiter( pMan );
p->timeSat += clock() - clk;

    // analyze the result
    RetValue = Fraig_ManCheckMiter( pMan );
//    assert( RetValue >= 0 );
    // save the pattern
    if ( RetValue == 0 )
Alan Mishchenko committed
161
    {
Alan Mishchenko committed
162 163 164 165 166 167 168 169 170 171 172 173 174
        // 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
175
    }
Alan Mishchenko committed
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
    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
192 193 194 195 196 197 198 199
}


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