blob: 70bb9c85009bf0795fe51ced9a39b3080cde46c6 [file] [log] [blame]
/**CFile****************************************************************
FileName [satChecker.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [SAT sat_solver.]
Synopsis [Resolution proof checker.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: satChecker.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 "misc/vec/vec.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sat_PrintClause( Vec_Vec_t * vClauses, int Clause )
{
Vec_Int_t * vClause;
int i, Entry;
printf( "Clause %d: {", Clause );
vClause = Vec_VecEntry( vClauses, Clause );
Vec_IntForEachEntry( vClause, Entry, i )
printf( " %d", Entry );
printf( " }\n" );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Sat_ProofResolve( Vec_Vec_t * vClauses, int Result, int Clause1, int Clause2 )
{
Vec_Int_t * vResult = Vec_VecEntry( vClauses, Result );
Vec_Int_t * vClause1 = Vec_VecEntry( vClauses, Clause1 );
Vec_Int_t * vClause2 = Vec_VecEntry( vClauses, Clause2 );
int Entry1, Entry2, ResVar;
int i, j, Counter = 0;
Vec_IntForEachEntry( vClause1, Entry1, i )
Vec_IntForEachEntry( vClause2, Entry2, j )
if ( Entry1 == -Entry2 )
{
ResVar = Entry1;
Counter++;
}
if ( Counter != 1 )
{
printf( "Error: Clause %d = Resolve(%d, %d): The number of pivot vars is %d.\n",
Result, Clause1, Clause2, Counter );
Sat_PrintClause( vClauses, Clause1 );
Sat_PrintClause( vClauses, Clause2 );
return 0;
}
// create new clause
assert( Vec_IntSize(vResult) == 0 );
Vec_IntForEachEntry( vClause1, Entry1, i )
if ( Entry1 != ResVar && Entry1 != -ResVar )
Vec_IntPushUnique( vResult, Entry1 );
assert( Vec_IntSize(vResult) + 1 == Vec_IntSize(vClause1) );
Vec_IntForEachEntry( vClause2, Entry2, i )
if ( Entry2 != ResVar && Entry2 != -ResVar )
Vec_IntPushUnique( vResult, Entry2 );
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sat_ProofChecker( char * pFileName )
{
FILE * pFile;
Vec_Vec_t * vClauses;
int c, i, Num, RetValue, Counter, Counter2, Clause1, Clause2;
int RetValue;
// open the file
pFile = fopen( pFileName, "r" );
if ( pFile == NULL )
return;
// count the number of clauses
Counter = Counter2 = 0;
while ( (c = fgetc(pFile)) != EOF )
{
Counter += (c == '\n');
Counter2 += (c == '*');
}
vClauses = Vec_VecStart( Counter+1 );
printf( "The proof contains %d roots and %d resolution steps.\n", Counter-Counter2, Counter2 );
// read the clauses
rewind( pFile );
for ( i = 1 ; ; i++ )
{
RetValue = RetValue = fscanf( pFile, "%d", &Num );
if ( RetValue != 1 )
break;
assert( Num == i );
while ( (c = fgetc( pFile )) == ' ' );
if ( c == '*' )
{
RetValue = fscanf( pFile, "%d %d", &Clause1, &Clause2 );
assert( RetValue == 2 );
RetValue = fscanf( pFile, "%d", &Num );
assert( RetValue == 1 );
assert( Num == 0 );
if ( !Sat_ProofResolve( vClauses, i, Clause1, Clause2 ) )
{
printf( "Error detected in the resolution proof.\n" );
Vec_VecFree( vClauses );
fclose( pFile );
return;
}
}
else
{
ungetc( c, pFile );
while ( 1 )
{
RetValue = fscanf( pFile, "%d", &Num );
assert( RetValue == 1 );
if ( Num == 0 )
break;
Vec_VecPush( vClauses, i, (void *)Num );
}
RetValue = fscanf( pFile, "%d", &Num );
assert( RetValue == 1 );
assert( Num == 0 );
}
}
assert( i-1 == Counter );
if ( Vec_IntSize( Vec_VecEntry(vClauses, Counter) ) != 0 )
printf( "The last clause is not empty.\n" );
else
printf( "The empty clause is derived.\n" );
Vec_VecFree( vClauses );
fclose( pFile );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END