from __future__ import print_function, absolute_import
import os
import signal
import sys
from netlib.version_check import check_pyopenssl_version, check_mitmproxy_version
from . import version, cmdline
from .exceptions import S/**CFile****************************************************************
FileName [satTruth.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [SAT solver.]
Synopsis [Truth table computation package.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: satTruth.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
***********************************************************************/
#include "satTruth.h"
#include "misc/vec/vecSet.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
struct Tru_Man_t_
{
int nVars; // the number of variables
int nWords; // the number of words in the truth table
int nEntrySize; // the size of one entry in 'int'
int nTableSize; // hash table size
int * pTable; // hash table
Vec_Set_t * pMem; // memory for truth tables
word * pZero; // temporary truth table
int hIthVars[16]; // variable handles
int nTableLookups;
};
typedef struct Tru_One_t_ Tru_One_t; // 16 bytes minimum
struct Tru_One_t_
{
int Handle; // support
int Next; // next one in the table
word pTruth[0]; // truth table
};
static inline Tru_One_t * Tru_ManReadOne( Tru_Man_t * p, int h ) { return h ? (Tru_One_t *)Vec_SetEntry(p->pMem, h) : NULL; }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns the hash key.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline unsigned Tru_ManHash( word * pTruth, int nWords, int nBins, int * pPrimes )
{
int i;
unsigned uHash = 0;
for ( i = 0; i < nWords; i++ )
uHash ^= pTruth[i] * pPrimes[i & 0x7];
return uHash % nBins;
}
/**Function*************************************************************
Synopsis [Returns the given record.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int * Tru_ManLookup( Tru_Man_t * p, word * pTruth )
{
static int s_Primes[10] = { 1291, 1699, 2357, 4177, 5147, 5647, 6343, 7103, 7873, 8147 };
Tru_One_t * pEntry;
int * pSpot;
assert( (pTruth[0] & 1) == 0 );
pSpot = p->pTable + Tru_ManHash( pTruth, p->nWords, p->nTableSize, s_Primes );
for ( pEntry = Tru_ManReadOne(p, *pSpot); pEntry; pSpot = &pEntry->Next, pEntry = Tru_ManReadOne(p, *pSpot) )
if ( Tru_ManEqual(pEntry->pTruth, pTruth, p->nWords) )
return pSpot;
return pSpot;
}
/**Function*************************************************************
Synopsis [Returns the given record.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tru_ManResize( Tru_Man_t * p )
{
Tru_One_t * pThis;
int * pTableOld, * pSpot;
int nTableSizeOld, iNext, Counter, i;
assert( p->pTable != NULL );
// replace the table
pTableOld = p->pTable;
nTableSizeOld = p->nTableSize;
p->nTableSize = 2 * p->nTableSize + 1;
p->pTable = ABC_CALLOC( int, p->nTableSize );
// rehash the entries from the old table
Counter = 0;
for ( i = 0; i < nTableSizeOld; i++ )
for ( pThis = Tru_ManReadOne(p, pTableOld[i]),
iNext = (pThis? pThis->Next : 0);
pThis; pThis = Tru_ManReadOne(p, iNext),
iNext = (pThis? pThis->Next : 0) )
{
assert( pThis->Handle );
pThis->Next = 0;
pSpot = Tru_ManLookup( p, pThis->pTruth );
assert( *pSpot == 0 ); // should not be there
*pSpot = pThis->Handle;
Counter++;
}
assert( Counter == Vec_SetEntryNum(p->pMem) );
ABC_FREE( pTableOld );
}
/**Function*************************************************************
Synopsis [Adds entry to the hash table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Tru_ManInsert( Tru_Man_t * p, word * pTruth )
{
int fCompl, * pSpot;
if ( Tru_ManEqual0(pTruth, p->nWords) )
return 0;
if ( Tru_ManEqual1(pTruth, p->nWords) )
return 1;
p->nTableLookups++;
if ( Vec_SetEntryNum(p->pMem) > 2 * p->nTableSize )
Tru_ManResize( p );
fCompl = pTruth[0] & 1;
if ( fCompl )
Tru_ManNot( pTruth, p->nWords );
pSpot = Tru_ManLookup( p, pTruth );
if ( *pSpot == 0 )
{
Tru_One_t * pEntry;
*pSpot = Vec_SetAppend( p->pMem, NULL, p->nEntrySize );
assert( (*pSpot & 1) == 0 );
pEntry = Tru_ManReadOne( p, *pSpot );
Tru_ManCopy( pEntry->pTruth, pTruth, p->nWords );
pEntry->Handle = *pSpot;
pEntry->Next = 0;
}
if ( fCompl )
Tru_ManNot( pTruth, p->nWords );
return *pSpot ^ fCompl;
}
/**Function*************************************************************
Synopsis [Start the truth table logging.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Tru_Man_t * Tru_ManAlloc( int nVars )
{
word Masks[6] =
{
ABC_CONST(0xAAAAAAAAAAAAAAAA),
ABC_CONST(0xCCCCCCCCCCCCCCCC),
ABC_CONST(0xF0F0F0F0F0F0F0F0),
ABC_CONST(0xFF00FF00FF00FF00),
ABC_CONST(0xFFFF0000FFFF0000),
ABC_CONST(0xFFFFFFFF00000000)
};
Tru_Man_t * p;
int i, w;
assert( nVars > 0 && nVars <= 16 );
p = ABC_CALLOC( Tru_Man_t, 1 );
p->nVars = nVars;
p->nWords = (nVars < 6) ? 1 : (1 << (nVars-6));
p->nEntrySize = (sizeof(Tru_One_t) + p->nWords * sizeof(word))/sizeof(int);
p->nTableSize = 8147;
p->pTable = ABC_CALLOC( int, p->nTableSize );
p->pMem = Vec_SetAlloc( 16 );
// initialize truth tables
p->pZero = ABC_ALLOC( word, p->nWords );
for ( i = 0; i < nVars; i++ )
{
for ( w = 0; w < p->nWords; w++ )
if ( i < 6 )
p->pZero[w] = Masks[i];
else if ( w & (1 << (i-6)) )
p->pZero[w] = ~(word)0;
else
p->pZero[w] = 0;
p->hIthVars[i] = Tru_ManInsert( p, p->pZero );
assert( !i || p->hIthVars[i] > p->hIthVars[i-1] );
}
Tru_ManClear( p->pZero, p->nWords );
return p;
}
/**Function*************************************************************
Synopsis [Stop the truth table logging.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tru_ManFree( Tru_Man_t * p )
{
printf( "Lookups = %d. Entries = %d.\n", p->nTableLookups, Vec_SetEntryNum(p->pMem) );
Vec_SetFree( p->pMem );
ABC_FREE( p->pZero );
ABC_FREE( p->pTable );
ABC_FREE( p );
}
/**Function*************************************************************
Synopsis [Returns elementary variable.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
word * Tru_ManVar( Tru_Man_t * p, int v )
{
assert( v >= 0 && v < p->nVars );
return Tru_ManReadOne( p, p->hIthVars[v] )->pTruth;
}
/**Function*************************************************************
Synopsis [Returns stored truth table]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
word * Tru_ManFunc( Tru_Man_t * p, int h )
{
assert( (h & 1) == 0 );
if ( h == 0 )
return p->pZero;
return Tru_ManReadOne( p, h )->pTruth;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END