mirror of https://github.com/YosysHQ/abc.git
470 lines
12 KiB
C
470 lines
12 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [satStore.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [SAT solver.]
|
|
|
|
Synopsis [Records the trace of SAT solving in the CNF form.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
Revision [$Id: satStore.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
#include "satStore.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Fetches memory.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
char * Sto_ManMemoryFetch( Sto_Man_t * p, int nBytes )
|
|
{
|
|
char * pMem;
|
|
if ( p->pChunkLast == NULL || nBytes > p->nChunkSize - p->nChunkUsed )
|
|
{
|
|
pMem = (char *)ABC_ALLOC( char, p->nChunkSize );
|
|
*(char **)pMem = p->pChunkLast;
|
|
p->pChunkLast = pMem;
|
|
p->nChunkUsed = sizeof(char *);
|
|
}
|
|
pMem = p->pChunkLast + p->nChunkUsed;
|
|
p->nChunkUsed += nBytes;
|
|
return pMem;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Frees memory manager.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Sto_ManMemoryStop( Sto_Man_t * p )
|
|
{
|
|
char * pMem, * pNext;
|
|
if ( p->pChunkLast == NULL )
|
|
return;
|
|
for ( pMem = p->pChunkLast; (pNext = *(char **)pMem); pMem = pNext )
|
|
ABC_FREE( pMem );
|
|
ABC_FREE( pMem );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Reports memory usage in bytes.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Sto_ManMemoryReport( Sto_Man_t * p )
|
|
{
|
|
int Total;
|
|
char * pMem, * pNext;
|
|
if ( p->pChunkLast == NULL )
|
|
return 0;
|
|
Total = p->nChunkUsed;
|
|
for ( pMem = p->pChunkLast; (pNext = *(char **)pMem); pMem = pNext )
|
|
Total += p->nChunkSize;
|
|
return Total;
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Allocate proof manager.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Sto_Man_t * Sto_ManAlloc()
|
|
{
|
|
Sto_Man_t * p;
|
|
// allocate the manager
|
|
p = (Sto_Man_t *)ABC_ALLOC( char, sizeof(Sto_Man_t) );
|
|
memset( p, 0, sizeof(Sto_Man_t) );
|
|
// memory management
|
|
p->nChunkSize = (1<<16); // use 64K chunks
|
|
return p;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Deallocate proof manager.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Sto_ManFree( Sto_Man_t * p )
|
|
{
|
|
Sto_ManMemoryStop( p );
|
|
ABC_FREE( p );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Adds one clause to the manager.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Sto_ManAddClause( Sto_Man_t * p, lit * pBeg, lit * pEnd )
|
|
{
|
|
Sto_Cls_t * pClause;
|
|
lit Lit, * i, * j;
|
|
int nSize;
|
|
|
|
// process the literals
|
|
if ( pBeg < pEnd )
|
|
{
|
|
// insertion sort
|
|
for ( i = pBeg + 1; i < pEnd; i++ )
|
|
{
|
|
Lit = *i;
|
|
for ( j = i; j > pBeg && *(j-1) > Lit; j-- )
|
|
*j = *(j-1);
|
|
*j = Lit;
|
|
}
|
|
// make sure there is no duplicated variables
|
|
for ( i = pBeg + 1; i < pEnd; i++ )
|
|
if ( lit_var(*(i-1)) == lit_var(*i) )
|
|
{
|
|
printf( "The clause contains two literals of the same variable: %d and %d.\n", *(i-1), *i );
|
|
return 0;
|
|
}
|
|
// check the largest var size
|
|
p->nVars = STO_MAX( p->nVars, lit_var(*(pEnd-1)) + 1 );
|
|
}
|
|
|
|
// get memory for the clause
|
|
nSize = sizeof(Sto_Cls_t) + sizeof(lit) * (pEnd - pBeg);
|
|
nSize = (nSize / sizeof(char*) + ((nSize % sizeof(char*)) > 0)) * sizeof(char*); // added by Saurabh on Sep 3, 2009
|
|
pClause = (Sto_Cls_t *)Sto_ManMemoryFetch( p, nSize );
|
|
memset( pClause, 0, sizeof(Sto_Cls_t) );
|
|
|
|
// assign the clause
|
|
pClause->Id = p->nClauses++;
|
|
pClause->nLits = pEnd - pBeg;
|
|
memcpy( pClause->pLits, pBeg, sizeof(lit) * (pEnd - pBeg) );
|
|
// assert( pClause->pLits[0] >= 0 );
|
|
|
|
// add the clause to the list
|
|
if ( p->pHead == NULL )
|
|
p->pHead = pClause;
|
|
if ( p->pTail == NULL )
|
|
p->pTail = pClause;
|
|
else
|
|
{
|
|
p->pTail->pNext = pClause;
|
|
p->pTail = pClause;
|
|
}
|
|
|
|
// add the empty clause
|
|
if ( pClause->nLits == 0 )
|
|
{
|
|
if ( p->pEmpty )
|
|
{
|
|
printf( "More than one empty clause!\n" );
|
|
return 0;
|
|
}
|
|
p->pEmpty = pClause;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Mark all clauses added so far as root clauses.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Sto_ManMarkRoots( Sto_Man_t * p )
|
|
{
|
|
Sto_Cls_t * pClause;
|
|
p->nRoots = 0;
|
|
Sto_ManForEachClause( p, pClause )
|
|
{
|
|
pClause->fRoot = 1;
|
|
p->nRoots++;
|
|
}
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Mark all clauses added so far as clause of A.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Sto_ManMarkClausesA( Sto_Man_t * p )
|
|
{
|
|
Sto_Cls_t * pClause;
|
|
p->nClausesA = 0;
|
|
Sto_ManForEachClause( p, pClause )
|
|
{
|
|
pClause->fA = 1;
|
|
p->nClausesA++;
|
|
}
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Returns the literal of the last clause.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Sto_ManChangeLastClause( Sto_Man_t * p )
|
|
{
|
|
Sto_Cls_t * pClause, * pPrev;
|
|
pPrev = NULL;
|
|
Sto_ManForEachClause( p, pClause )
|
|
pPrev = pClause;
|
|
assert( pPrev != NULL );
|
|
assert( pPrev->fA == 1 );
|
|
assert( pPrev->nLits == 1 );
|
|
p->nClausesA--;
|
|
pPrev->fA = 0;
|
|
return pPrev->pLits[0] >> 1;
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Writes the stored clauses into a file.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Sto_ManDumpClauses( Sto_Man_t * p, char * pFileName )
|
|
{
|
|
FILE * pFile;
|
|
Sto_Cls_t * pClause;
|
|
int i;
|
|
// start the file
|
|
pFile = fopen( pFileName, "w" );
|
|
if ( pFile == NULL )
|
|
{
|
|
printf( "Error: Cannot open output file (%s).\n", pFileName );
|
|
return;
|
|
}
|
|
// write the data
|
|
fprintf( pFile, "p %d %d %d %d\n", p->nVars, p->nClauses, p->nRoots, p->nClausesA );
|
|
Sto_ManForEachClause( p, pClause )
|
|
{
|
|
for ( i = 0; i < (int)pClause->nLits; i++ )
|
|
fprintf( pFile, " %d", lit_print(pClause->pLits[i]) );
|
|
fprintf( pFile, " 0\n" );
|
|
}
|
|
// fprintf( pFile, " 0\n" );
|
|
fclose( pFile );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Reads one literal from file.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Sto_ManLoadNumber( FILE * pFile, int * pNumber )
|
|
{
|
|
int Char, Number = 0, Sign = 0;
|
|
// skip space-like chars
|
|
do {
|
|
Char = fgetc( pFile );
|
|
if ( Char == EOF )
|
|
return 0;
|
|
} while ( Char == ' ' || Char == '\t' || Char == '\r' || Char == '\n' );
|
|
// read the literal
|
|
while ( 1 )
|
|
{
|
|
// get the next character
|
|
Char = fgetc( pFile );
|
|
if ( Char == ' ' || Char == '\t' || Char == '\r' || Char == '\n' )
|
|
break;
|
|
// check that the char is a digit
|
|
if ( (Char < '0' || Char > '9') && Char != '-' )
|
|
{
|
|
printf( "Error: Wrong char (%c) in the input file.\n", Char );
|
|
return 0;
|
|
}
|
|
// check if this is a minus
|
|
if ( Char == '-' )
|
|
Sign = 1;
|
|
else
|
|
Number = 10 * Number + Char;
|
|
}
|
|
// return the number
|
|
*pNumber = Sign? -Number : Number;
|
|
return 1;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Reads CNF from file.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Sto_Man_t * Sto_ManLoadClauses( char * pFileName )
|
|
{
|
|
FILE * pFile;
|
|
Sto_Man_t * p;
|
|
Sto_Cls_t * pClause;
|
|
char pBuffer[1024];
|
|
int nLits, nLitsAlloc, Counter, Number;
|
|
lit * pLits;
|
|
|
|
// start the file
|
|
pFile = fopen( pFileName, "r" );
|
|
if ( pFile == NULL )
|
|
{
|
|
printf( "Error: Cannot open input file (%s).\n", pFileName );
|
|
return NULL;
|
|
}
|
|
|
|
// create the manager
|
|
p = Sto_ManAlloc();
|
|
|
|
// alloc the array of literals
|
|
nLitsAlloc = 1024;
|
|
pLits = (lit *)ABC_ALLOC( char, sizeof(lit) * nLitsAlloc );
|
|
|
|
// read file header
|
|
p->nVars = p->nClauses = p->nRoots = p->nClausesA = 0;
|
|
while ( fgets( pBuffer, 1024, pFile ) )
|
|
{
|
|
if ( pBuffer[0] == 'c' )
|
|
continue;
|
|
if ( pBuffer[0] == 'p' )
|
|
{
|
|
sscanf( pBuffer + 1, "%d %d %d %d", &p->nVars, &p->nClauses, &p->nRoots, &p->nClausesA );
|
|
break;
|
|
}
|
|
printf( "Warning: Skipping line: \"%s\"\n", pBuffer );
|
|
}
|
|
|
|
// read the clauses
|
|
nLits = 0;
|
|
while ( Sto_ManLoadNumber(pFile, &Number) )
|
|
{
|
|
if ( Number == 0 )
|
|
{
|
|
int RetValue;
|
|
RetValue = Sto_ManAddClause( p, pLits, pLits + nLits );
|
|
assert( RetValue );
|
|
nLits = 0;
|
|
continue;
|
|
}
|
|
if ( nLits == nLitsAlloc )
|
|
{
|
|
nLitsAlloc *= 2;
|
|
pLits = ABC_REALLOC( lit, pLits, nLitsAlloc );
|
|
}
|
|
pLits[ nLits++ ] = lit_read(Number);
|
|
}
|
|
if ( nLits > 0 )
|
|
printf( "Error: The last clause was not saved.\n" );
|
|
|
|
// count clauses
|
|
Counter = 0;
|
|
Sto_ManForEachClause( p, pClause )
|
|
Counter++;
|
|
|
|
// check the number of clauses
|
|
if ( p->nClauses != Counter )
|
|
{
|
|
printf( "Error: The actual number of clauses (%d) is different than declared (%d).\n", Counter, p->nClauses );
|
|
Sto_ManFree( p );
|
|
return NULL;
|
|
}
|
|
|
|
ABC_FREE( pLits );
|
|
fclose( pFile );
|
|
return p;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|