src/sat/proof/pr.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#include "pr.h"
Include dependency graph for pr.c:

Go to the source code of this file.

Data Structures

struct  Pr_Cls_t_
struct  Pr_Man_t_

Defines

#define Pr_ManForEachClause(p, pCls)   for( pCls = p->pHead; pCls; pCls = pCls->pNext )
#define Pr_ManForEachClauseRoot(p, pCls)   for( pCls = p->pHead; pCls != p->pLearnt; pCls = pCls->pNext )
#define Pr_ManForEachClauseLearnt(p, pCls)   for( pCls = p->pLearnt; pCls; pCls = pCls->pNext )

Typedefs

typedef unsigned lit
typedef struct Pr_Cls_t_ Pr_Cls_t

Functions

static lit toLit (int v)
static lit toLitCond (int v, int c)
static lit lit_neg (lit l)
static int lit_var (lit l)
static int lit_sign (lit l)
static int lit_print (lit l)
static lit lit_read (int s)
static int lit_check (lit l, int n)
static char * Pr_ManMemoryFetch (Pr_Man_t *p, int nBytes)
static void Pr_ManMemoryStop (Pr_Man_t *p)
static void Pr_ManResize (Pr_Man_t *p, int nVarsNew)
Pr_Man_tPr_ManAlloc (int nVarsAlloc)
void Pr_ManFree (Pr_Man_t *p)
int Pr_ManAddClause (Pr_Man_t *p, lit *pBeg, lit *pEnd, int fRoot, int fClauseA)
int Pr_ManProofWrite (Pr_Man_t *p)
static void Pr_ManWatchClause (Pr_Man_t *p, Pr_Cls_t *pClause, lit Lit)
int Pr_ManMemoryReport (Pr_Man_t *p)
void Extra_PrintBinary_ (FILE *pFile, unsigned Sign[], int nBits)
void Pr_ManPrintInterOne (Pr_Man_t *p, Pr_Cls_t *pClause)
static int Pr_ManEnqueue (Pr_Man_t *p, lit Lit, Pr_Cls_t *pReason)
static void Pr_ManCancelUntil (Pr_Man_t *p, int Level)
static Pr_Cls_tPr_ManPropagateOne (Pr_Man_t *p, lit Lit)
Pr_Cls_tPr_ManPropagate (Pr_Man_t *p, int Start)
void Pr_ManPrintClause (Pr_Cls_t *pClause)
void Pr_ManPrintResolvent (lit *pResLits, int nResLits)
void Pr_ManProofWriteOne (Pr_Man_t *p, Pr_Cls_t *pClause)
int Pr_ManProofTraceOne (Pr_Man_t *p, Pr_Cls_t *pConflict, Pr_Cls_t *pFinal)
int Pr_ManProofRecordOne (Pr_Man_t *p, Pr_Cls_t *pClause)
int Pr_ManProcessRoots (Pr_Man_t *p)
void Pr_ManPrepareInter (Pr_Man_t *p)
Pr_Man_tPr_ManProofRead (char *pFileName)
int Pr_ManProofTest (char *pFileName)

Variables

static const lit LIT_UNDEF = 0xffffffff

Define Documentation

#define Pr_ManForEachClause ( p,
pCls   )     for( pCls = p->pHead; pCls; pCls = pCls->pNext )

Definition at line 112 of file pr.c.

#define Pr_ManForEachClauseLearnt ( p,
pCls   )     for( pCls = p->pLearnt; pCls; pCls = pCls->pNext )

Definition at line 114 of file pr.c.

#define Pr_ManForEachClauseRoot ( p,
pCls   )     for( pCls = p->pHead; pCls != p->pLearnt; pCls = pCls->pNext )

Definition at line 113 of file pr.c.


Typedef Documentation

typedef unsigned lit

CFile****************************************************************

FileName [pr.c]

SystemName [ABC: Logic synthesis and verification system.]

PackageName [Proof recording.]

Synopsis [Core procedures of the package.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

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

Revision [

Id
pr.c,v 1.00 2005/06/20 00:00:00 alanmi Exp

] DECLARATIONS ///

Definition at line 33 of file pr.c.

typedef struct Pr_Cls_t_ Pr_Cls_t

Definition at line 35 of file pr.c.


Function Documentation

void Extra_PrintBinary_ ( FILE *  pFile,
unsigned  Sign[],
int  nBits 
)

Function*************************************************************

Synopsis [Records the proof.]

Description []

SideEffects []

SeeAlso []

Definition at line 416 of file pr.c.

00417 {
00418     int Remainder, nWords;
00419     int w, i;
00420 
00421     Remainder = (nBits%(sizeof(unsigned)*8));
00422     nWords    = (nBits/(sizeof(unsigned)*8)) + (Remainder>0);
00423 
00424     for ( w = nWords-1; w >= 0; w-- )
00425         for ( i = ((w == nWords-1 && Remainder)? Remainder-1: 31); i >= 0; i-- )
00426             fprintf( pFile, "%c", '0' + (int)((Sign[w] & (1<<i)) > 0) );
00427 }

static int lit_check ( lit  l,
int  n 
) [inline, static]

Definition at line 109 of file pr.c.

00109 { return l >= 0 && lit_var(l) < n;                  }

static lit lit_neg ( lit  l  )  [inline, static]

Definition at line 104 of file pr.c.

00104 { return l ^ 1;  }

static int lit_print ( lit  l  )  [inline, static]

Definition at line 107 of file pr.c.

00107 { return lit_sign(l)? -lit_var(l)-1 : lit_var(l)+1; }

static lit lit_read ( int  s  )  [inline, static]

Definition at line 108 of file pr.c.

00108 { return s > 0 ? toLit(s-1) : lit_neg(toLit(-s-1)); }

static int lit_sign ( lit  l  )  [inline, static]

Definition at line 106 of file pr.c.

00106 { return l & 1;  }

static int lit_var ( lit  l  )  [inline, static]

Definition at line 105 of file pr.c.

00105 { return l >> 1; }

int Pr_ManAddClause ( Pr_Man_t p,
lit pBeg,
lit pEnd,
int  fRoot,
int  fClauseA 
)

Function*************************************************************

Synopsis [Adds one clause to the manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 269 of file pr.c.

00270 {
00271     Pr_Cls_t * pClause;
00272     lit Lit, * i, * j;
00273     int nSize, VarMax;
00274 
00275     // process the literals
00276     if ( pBeg < pEnd )
00277     {
00278         // insertion sort
00279         VarMax = lit_var( *pBeg );
00280         for ( i = pBeg + 1; i < pEnd; i++ )
00281         {
00282             Lit = *i;
00283             VarMax = lit_var(Lit) > VarMax ? lit_var(Lit) : VarMax;
00284             for ( j = i; j > pBeg && *(j-1) > Lit; j-- )
00285                 *j = *(j-1);
00286             *j = Lit;
00287         }
00288         // make sure there is no duplicated variables
00289         for ( i = pBeg + 1; i < pEnd; i++ )
00290             assert( lit_var(*(i-1)) != lit_var(*i) );
00291         // resize the manager
00292         Pr_ManResize( p, VarMax+1 );
00293     }
00294 
00295     // get memory for the clause
00296     nSize = sizeof(Pr_Cls_t) + sizeof(lit) * (pEnd - pBeg);
00297     pClause = (Pr_Cls_t *)Pr_ManMemoryFetch( p, nSize );
00298     memset( pClause, 0, sizeof(Pr_Cls_t) );
00299 
00300     // assign the clause
00301     assert( !fClauseA || fRoot ); // clause of A is always a root clause
00302     p->nRoots += fRoot;
00303     p->nClausesA += fClauseA;
00304     pClause->Id = p->nClauses++;
00305     pClause->fA = fClauseA;
00306     pClause->fRoot = fRoot;
00307     pClause->nLits = pEnd - pBeg;
00308     memcpy( pClause->pLits, pBeg, sizeof(lit) * (pEnd - pBeg) );
00309 
00310     // add the clause to the list
00311     if ( p->pHead == NULL )
00312         p->pHead = pClause;
00313     if ( p->pTail == NULL )
00314         p->pTail = pClause;
00315     else
00316     {
00317         p->pTail->pNext = pClause;
00318         p->pTail = pClause;
00319     }
00320 
00321     // mark the first learnt clause
00322     if ( p->pLearnt == NULL && !pClause->fRoot )
00323         p->pLearnt = pClause;
00324 
00325     // add the empty clause
00326     if ( pClause->nLits == 0 )
00327     {
00328         if ( p->pEmpty )
00329             printf( "More than one empty clause!\n" );
00330         p->pEmpty = pClause;
00331     }
00332     return 1;
00333 }

Pr_Man_t * Pr_ManAlloc ( int  nVarsAlloc  ) 

FUNCTION DEFINITIONS ///Function*************************************************************

Synopsis [Allocate proof manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 142 of file pr.c.

00143 {
00144     Pr_Man_t * p;
00145     // allocate the manager
00146     p = (Pr_Man_t *)malloc( sizeof(Pr_Man_t) );
00147     memset( p, 0, sizeof(Pr_Man_t) );
00148     // allocate internal arrays
00149     Pr_ManResize( p, nVarsAlloc? nVarsAlloc : 256 );
00150     // set the starting number of variables
00151     p->nVars = 0;
00152     // memory management
00153     p->nChunkSize = (1<<16); // use 64K chunks
00154     // verification
00155     p->nResLitsAlloc = (1<<16);
00156     p->pResLits = malloc( sizeof(lit) * p->nResLitsAlloc );
00157     // parameters
00158     p->fProofWrite = 0;
00159     p->fProofVerif = 0;
00160     return p;    
00161 }

static void Pr_ManCancelUntil ( Pr_Man_t p,
int  Level 
) [inline, static]

Function*************************************************************

Synopsis [Records implication.]

Description []

SideEffects []

SeeAlso []

Definition at line 483 of file pr.c.

00484 {
00485     lit Lit;
00486     int i, Var;
00487     for ( i = p->nTrailSize - 1; i >= Level; i-- )
00488     {
00489         Lit = p->pTrail[i];
00490         Var = lit_var( Lit );
00491         p->pReasons[Var] = NULL;
00492         p->pAssigns[Var] = LIT_UNDEF;
00493 //printf( "cancelling var %d\n", Var );
00494     }
00495     p->nTrailSize = Level;
00496 }

static int Pr_ManEnqueue ( Pr_Man_t p,
lit  Lit,
Pr_Cls_t pReason 
) [inline, static]

Function*************************************************************

Synopsis [Records implication.]

Description []

SideEffects []

SeeAlso []

Definition at line 460 of file pr.c.

00461 {
00462     int Var = lit_var(Lit);
00463     if ( p->pAssigns[Var] != LIT_UNDEF )
00464         return p->pAssigns[Var] == Lit;
00465     p->pAssigns[Var] = Lit;
00466     p->pReasons[Var] = pReason;
00467     p->pTrail[p->nTrailSize++] = Lit;
00468 //printf( "assigning var %d value %d\n", Var, !lit_sign(Lit) );
00469     return 1;
00470 }

void Pr_ManFree ( Pr_Man_t p  ) 

Function*************************************************************

Synopsis [Deallocate proof manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 215 of file pr.c.

00216 {
00217     printf( "Runtime stats:\n" );
00218 PRT( "Reading ", p->timeRead  );
00219 PRT( "BCP     ", p->timeBcp   );
00220 PRT( "Trace   ", p->timeTrace );
00221 PRT( "TOTAL   ", p->timeTotal );
00222 
00223     Pr_ManMemoryStop( p );
00224     free( p->pTrail );
00225     free( p->pAssigns );
00226     free( p->pSeens );
00227     free( p->pVarTypes );
00228     free( p->pReasons );
00229     free( p->pWatches );
00230     free( p->pResLits );
00231     free( p );
00232 }

char * Pr_ManMemoryFetch ( Pr_Man_t p,
int  nBytes 
) [static]

Function*************************************************************

Synopsis [Fetches memory.]

Description []

SideEffects []

SeeAlso []

Definition at line 346 of file pr.c.

00347 {
00348     char * pMem;
00349     if ( p->pChunkLast == NULL || nBytes > p->nChunkSize - p->nChunkUsed )
00350     {
00351         pMem = (char *)malloc( p->nChunkSize );
00352         *(char **)pMem = p->pChunkLast;
00353         p->pChunkLast = pMem;
00354         p->nChunkUsed = sizeof(char *);
00355     }
00356     pMem = p->pChunkLast + p->nChunkUsed;
00357     p->nChunkUsed += nBytes;
00358     return pMem;
00359 }

int Pr_ManMemoryReport ( Pr_Man_t p  ) 

Function*************************************************************

Synopsis [Reports memory usage in bytes.]

Description []

SideEffects []

SeeAlso []

Definition at line 393 of file pr.c.

00394 {
00395     int Total;
00396     char * pMem, * pNext;
00397     if ( p->pChunkLast == NULL )
00398         return 0;
00399     Total = p->nChunkUsed; 
00400     for ( pMem = p->pChunkLast; pNext = *(char **)pMem; pMem = pNext )
00401         Total += p->nChunkSize;
00402     return Total;
00403 }

void Pr_ManMemoryStop ( Pr_Man_t p  )  [static]

Function*************************************************************

Synopsis [Frees memory manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 372 of file pr.c.

00373 {
00374     char * pMem, * pNext;
00375     if ( p->pChunkLast == NULL )
00376         return;
00377     for ( pMem = p->pChunkLast; pNext = *(char **)pMem; pMem = pNext )
00378         free( pMem );
00379     free( pMem );
00380 }

void Pr_ManPrepareInter ( Pr_Man_t p  ) 

Function*************************************************************

Synopsis [Records the proof.]

Description []

SideEffects []

SeeAlso []

Definition at line 974 of file pr.c.

00975 {
00976     unsigned uTruths[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
00977     Pr_Cls_t * pClause;
00978     int Var, v;
00979 
00980     // mark the variable encountered in the clauses of A
00981     Pr_ManForEachClauseRoot( p, pClause )
00982     {
00983         if ( !pClause->fA )
00984             break;
00985         for ( v = 0; v < (int)pClause->nLits; v++ )
00986             p->pVarTypes[lit_var(pClause->pLits[v])] = 1;
00987     }
00988 
00989     // check variables that appear in clauses of B
00990     p->nVarsAB = 0;
00991     Pr_ManForEachClauseRoot( p, pClause )
00992     {
00993         if ( pClause->fA )
00994             continue;
00995         for ( v = 0; v < (int)pClause->nLits; v++ )
00996         {
00997             Var = lit_var(pClause->pLits[v]);
00998             if ( p->pVarTypes[Var] == 1 ) // var of A
00999             {
01000                 // change it into a global variable
01001                 p->nVarsAB++;
01002                 p->pVarTypes[Var] = -1;
01003             }
01004         }
01005     }
01006 
01007     // order global variables
01008     p->nVarsAB = 0;
01009     for ( v = 0; v < p->nVars; v++ )
01010         if ( p->pVarTypes[v] == -1 )
01011             p->pVarTypes[v] -= p->nVarsAB++;
01012 printf( "There are %d global variables.\n", p->nVarsAB );
01013 
01014     // set interpolants for root clauses
01015     Pr_ManForEachClauseRoot( p, pClause )
01016     {
01017         if ( !pClause->fA ) // clause of B
01018         {
01019             pClause->uTruth = ~0;
01020             Pr_ManPrintInterOne( p, pClause );
01021             continue;
01022         }
01023         // clause of A
01024         pClause->uTruth = 0;
01025         for ( v = 0; v < (int)pClause->nLits; v++ )
01026         {
01027             Var = lit_var(pClause->pLits[v]);
01028             if ( p->pVarTypes[Var] < 0 ) // global var
01029             {
01030                 if ( lit_sign(pClause->pLits[v]) ) // negative var
01031                     pClause->uTruth |= ~uTruths[ -p->pVarTypes[Var]-1 ];
01032                 else
01033                     pClause->uTruth |= uTruths[ -p->pVarTypes[Var]-1 ];
01034             }
01035         }
01036         Pr_ManPrintInterOne( p, pClause );
01037     }
01038 }

void Pr_ManPrintClause ( Pr_Cls_t pClause  ) 

Function*************************************************************

Synopsis [Prints the clause.]

Description []

SideEffects []

SeeAlso []

Definition at line 608 of file pr.c.

00609 {
00610     int i;
00611     printf( "Clause ID = %d. Proof = %d. {", pClause->Id, (int)pClause->pProof );
00612     for ( i = 0; i < (int)pClause->nLits; i++ )
00613         printf( " %d", pClause->pLits[i] );
00614     printf( " }\n" );
00615 }

void Pr_ManPrintInterOne ( Pr_Man_t p,
Pr_Cls_t pClause 
)

Function*************************************************************

Synopsis [Prints the interpolant for one clause.]

Description []

SideEffects []

SeeAlso []

Definition at line 440 of file pr.c.

00441 {
00442     printf( "Clause %2d :  ", pClause->Id );
00443     Extra_PrintBinary_( stdout, &pClause->uTruth, (1 << p->nVarsAB) );
00444     printf( "\n" );
00445 }

void Pr_ManPrintResolvent ( lit pResLits,
int  nResLits 
)

Function*************************************************************

Synopsis [Prints the resolvent.]

Description []

SideEffects []

SeeAlso []

Definition at line 628 of file pr.c.

00629 {
00630     int i;
00631     printf( "Resolvent: {" );
00632     for ( i = 0; i < nResLits; i++ )
00633         printf( " %d", pResLits[i] );
00634     printf( " }\n" );
00635 }

int Pr_ManProcessRoots ( Pr_Man_t p  ) 

Function*************************************************************

Synopsis [Propagate the root clauses.]

Description []

SideEffects []

SeeAlso []

Definition at line 906 of file pr.c.

00907 {
00908     Pr_Cls_t * pClause;
00909     int Counter;
00910 
00911     // make sure the root clauses are preceeding the learnt clauses
00912     Counter = 0;
00913     Pr_ManForEachClause( p, pClause )
00914     {
00915         assert( (int)pClause->fA    == (Counter < (int)p->nClausesA) );
00916         assert( (int)pClause->fRoot == (Counter < (int)p->nRoots)    );
00917         Counter++;
00918     }
00919     assert( p->nClauses == Counter );
00920 
00921     // make sure the last clause if empty
00922     assert( p->pTail->nLits == 0 );
00923 
00924     // go through the root unit clauses
00925     p->nTrailSize = 0;
00926     Pr_ManForEachClauseRoot( p, pClause )
00927     {
00928         // create watcher lists for the root clauses
00929         if ( pClause->nLits > 1 )
00930         {
00931             Pr_ManWatchClause( p, pClause, pClause->pLits[0] );
00932             Pr_ManWatchClause( p, pClause, pClause->pLits[1] );
00933         }
00934         // empty clause and large clauses
00935         if ( pClause->nLits != 1 )
00936             continue;
00937         // unit clause
00938         assert( lit_check(pClause->pLits[0], p->nVars) );
00939         if ( !Pr_ManEnqueue( p, pClause->pLits[0], pClause ) )
00940         {
00941             // detected root level conflict
00942             printf( "Pr_ManProcessRoots(): Detected a root-level conflict\n" );
00943             assert( 0 );
00944             return 0;
00945         }
00946     }
00947 
00948     // propagate the root unit clauses
00949     pClause = Pr_ManPropagate( p, 0 );
00950     if ( pClause )
00951     {
00952         // detected root level conflict
00953         printf( "Pr_ManProcessRoots(): Detected a root-level conflict\n" );
00954         assert( 0 );
00955         return 0;
00956     }
00957 
00958     // set the root level
00959     p->nRootSize = p->nTrailSize;
00960     return 1;
00961 }

Pr_Man_t* Pr_ManProofRead ( char *  pFileName  ) 

Function*************************************************************

Synopsis [Reads clauses from file.]

Description []

SideEffects []

SeeAlso []

Definition at line 1109 of file pr.c.

01110 {
01111     Pr_Man_t * p = NULL;
01112     char * pCur, * pBuffer = NULL;
01113     int * pArray = NULL;
01114     FILE * pFile;
01115     int RetValue, Counter, nNumbers, Temp;
01116     int nClauses, nClausesA, nRoots, nVars;
01117 
01118     // open the file
01119     pFile = fopen( pFileName, "r" );
01120     if ( pFile == NULL )
01121     {
01122         printf( "Count not open input file \"%s\".\n", pFileName );
01123         return NULL;
01124     }
01125 
01126     // read the file
01127     pBuffer = (char *)malloc( (1<<16) );
01128     for ( Counter = 0; fgets( pBuffer, (1<<16), pFile ); )
01129     {
01130         if ( pBuffer[0] == 'c' )
01131             continue;
01132         if ( pBuffer[0] == 'p' )
01133         {
01134             assert( p == NULL );
01135             nClausesA = 0;
01136             RetValue = sscanf( pBuffer + 1, "%d %d %d %d", &nVars, &nClauses, &nRoots, &nClausesA );
01137             if ( RetValue != 3 && RetValue != 4 )
01138             {
01139                 printf( "Wrong input file format.\n" );
01140             }
01141             p = Pr_ManAlloc( nVars );
01142             pArray = (int *)malloc( sizeof(int) * (nVars + 10) );
01143             continue;
01144         }
01145         // skip empty lines
01146         for ( pCur = pBuffer; *pCur; pCur++ )
01147             if ( !(*pCur == ' ' || *pCur == '\t' || *pCur == '\r' || *pCur == '\n') )
01148                 break;
01149         if ( *pCur == 0 )
01150             continue;
01151         // scan the numbers from file
01152         nNumbers = 0;
01153         pCur = pBuffer;
01154         while ( *pCur )
01155         {
01156             // skip spaces
01157             for ( ; *pCur && *pCur == ' '; pCur++ );
01158             // read next number
01159             Temp = 0;
01160             sscanf( pCur, "%d", &Temp );
01161             if ( Temp == 0 )
01162                 break;
01163             pArray[ nNumbers++ ] = lit_read( Temp );
01164             // skip non-spaces
01165             for ( ; *pCur && *pCur != ' '; pCur++ );
01166         }
01167         // add the clause
01168         if ( !Pr_ManAddClause( p, pArray, pArray + nNumbers, Counter < nRoots, Counter < nClausesA ) )
01169         {
01170             printf( "Bad clause number %d.\n", Counter );
01171             return NULL;
01172         }
01173         // count the clauses
01174         Counter++;
01175     }
01176     // check the number of clauses
01177     if ( Counter != nClauses )
01178         printf( "Expected %d clauses but read %d.\n", nClauses, Counter );
01179 
01180     // finish
01181     if ( pArray ) free( pArray );
01182     if ( pBuffer ) free( pBuffer );
01183     fclose( pFile );
01184     return p;
01185 }

int Pr_ManProofRecordOne ( Pr_Man_t p,
Pr_Cls_t pClause 
)

Function*************************************************************

Synopsis [Records the proof for one clause.]

Description []

SideEffects []

SeeAlso []

Definition at line 830 of file pr.c.

00831 {
00832     Pr_Cls_t * pConflict;
00833     int i;
00834 
00835     // empty clause never ends up there
00836     assert( pClause->nLits > 0 );
00837     if ( pClause->nLits == 0 )
00838         printf( "Error: Empty clause is attempted.\n" );
00839 
00840     // add assumptions to the trail
00841     assert( !pClause->fRoot );
00842     assert( p->nTrailSize == p->nRootSize );
00843     for ( i = 0; i < (int)pClause->nLits; i++ )
00844         if ( !Pr_ManEnqueue( p, lit_neg(pClause->pLits[i]), NULL ) )
00845         {
00846             assert( 0 ); // impossible
00847             return 0;
00848         }
00849 
00850     // propagate the assumptions
00851     pConflict = Pr_ManPropagate( p, p->nRootSize );
00852     if ( pConflict == NULL )
00853     {
00854         assert( 0 ); // cannot prove
00855         return 0;
00856     }
00857 
00858     // construct the proof
00859     pClause->pProof = (void *)Pr_ManProofTraceOne( p, pConflict, pClause );
00860 
00861     // undo to the root level
00862     Pr_ManCancelUntil( p, p->nRootSize );
00863 
00864     // add large clauses to the watched lists
00865     if ( pClause->nLits > 1 )
00866     {
00867         Pr_ManWatchClause( p, pClause, pClause->pLits[0] );
00868         Pr_ManWatchClause( p, pClause, pClause->pLits[1] );
00869         return 1;
00870     }
00871     assert( pClause->nLits == 1 );
00872 
00873     // if the clause proved is unit, add it and propagate
00874     if ( !Pr_ManEnqueue( p, pClause->pLits[0], pClause ) )
00875     {
00876         assert( 0 ); // impossible
00877         return 0;
00878     }
00879 
00880     // propagate the assumption
00881     pConflict = Pr_ManPropagate( p, p->nRootSize );
00882     if ( pConflict )
00883     {
00884         // construct the proof
00885         p->pEmpty->pProof = (void *)Pr_ManProofTraceOne( p, pConflict, p->pEmpty );
00886         printf( "Found last conflict after adding unit clause number %d!\n", pClause->Id );
00887         return 0;
00888     }
00889 
00890     // update the root level
00891     p->nRootSize = p->nTrailSize;
00892     return 1;
00893 }

int Pr_ManProofTest ( char *  pFileName  ) 

Function*************************************************************

Synopsis [Records the proof.]

Description []

SideEffects []

SeeAlso []Function*************************************************************

Synopsis [Records the proof.]

Description []

SideEffects []

SeeAlso []

Definition at line 1227 of file pr.c.

01228 {
01229     Pr_Man_t * p;
01230     int clk, clkTotal = clock();
01231 
01232 clk = clock();
01233     p = Pr_ManProofRead( pFileName );
01234 p->timeRead = clock() - clk;
01235     if ( p == NULL )
01236         return 0;
01237 
01238     Pr_ManProofWrite( p );
01239 
01240     // print stats
01241 /*
01242     nUsed = Pr_ManProofCount_rec( p->pEmpty );
01243     printf( "Roots = %d. Learned = %d. Total = %d. Steps = %d.  Ave = %.2f.  Used = %d. Ratio = %.2f. \n", 
01244         p->nRoots, p->nClauses-p->nRoots, p->nClauses, p->Counter,  
01245         1.0*(p->Counter-p->nRoots)/(p->nClauses-p->nRoots),
01246         nUsed, 1.0*nUsed/(p->nClauses-p->nRoots)  );
01247 */
01248     printf( "Vars = %d. Roots = %d. Learned = %d. Resol steps = %d.  Ave = %.2f.  Mem = %.2f Mb\n", 
01249         p->nVars, p->nRoots, p->nClauses-p->nRoots, p->Counter,  
01250         1.0*(p->Counter-p->nRoots)/(p->nClauses-p->nRoots), 
01251         1.0*Pr_ManMemoryReport(p)/(1<<20) );
01252 
01253 p->timeTotal = clock() - clkTotal;
01254     Pr_ManFree( p );
01255     return 1;
01256 }

int Pr_ManProofTraceOne ( Pr_Man_t p,
Pr_Cls_t pConflict,
Pr_Cls_t pFinal 
)

Function*************************************************************

Synopsis [Traces the proof for one clause.]

Description []

SideEffects []

SeeAlso []

Definition at line 673 of file pr.c.

00674 {
00675     Pr_Cls_t * pReason;
00676     int i, v, Var, PrevId;
00677     int fPrint = 0;
00678     int clk = clock();
00679 
00680     // collect resolvent literals
00681     if ( p->fProofVerif )
00682     {
00683         assert( (int)pConflict->nLits <= p->nResLitsAlloc );
00684         memcpy( p->pResLits, pConflict->pLits, sizeof(lit) * pConflict->nLits );
00685         p->nResLits = pConflict->nLits;
00686     }
00687 
00688     // mark all the variables in the conflict as seen
00689     for ( v = 0; v < (int)pConflict->nLits; v++ )
00690         p->pSeens[lit_var(pConflict->pLits[v])] = 1;
00691 
00692     // start the anticedents
00693 //    pFinal->pAntis = Vec_PtrAlloc( 32 );
00694 //    Vec_PtrPush( pFinal->pAntis, pConflict );
00695 
00696     if ( p->nClausesA )
00697         pFinal->uTruth = pConflict->uTruth;
00698    
00699     // follow the trail backwards
00700     PrevId = (int)pConflict->pProof;
00701     for ( i = p->nTrailSize - 1; i >= 0; i-- )
00702     {
00703         // skip literals that are not involved
00704         Var = lit_var(p->pTrail[i]);
00705         if ( !p->pSeens[Var] )
00706             continue;
00707         p->pSeens[Var] = 0;
00708 
00709         // skip literals of the resulting clause
00710         pReason = p->pReasons[Var];
00711         if ( pReason == NULL )
00712             continue;
00713         assert( p->pTrail[i] == pReason->pLits[0] );
00714 
00715         // add the variables to seen
00716         for ( v = 1; v < (int)pReason->nLits; v++ )
00717             p->pSeens[lit_var(pReason->pLits[v])] = 1;
00718 
00719 
00720         // record the reason clause
00721         assert( pReason->pProof > 0 );
00722         p->Counter++;
00723         if ( p->fProofWrite )
00724             fprintf( p->pManProof, "%d * %d %d 0\n", p->Counter, PrevId, (int)pReason->pProof );
00725         PrevId = p->Counter;
00726 
00727         if ( p->nClausesA )
00728         {
00729             if ( p->pVarTypes[Var] == 1 ) // var of A
00730                 pFinal->uTruth |= pReason->uTruth;
00731             else
00732                 pFinal->uTruth &= pReason->uTruth;
00733         }
00734  
00735         // resolve the temporary resolvent with the reason clause
00736         if ( p->fProofVerif )
00737         {
00738             int v1, v2; 
00739             if ( fPrint )
00740                 Pr_ManPrintResolvent( p->pResLits, p->nResLits );
00741             // check that the var is present in the resolvent
00742             for ( v1 = 0; v1 < p->nResLits; v1++ )
00743                 if ( lit_var(p->pResLits[v1]) == Var )
00744                     break;
00745             if ( v1 == p->nResLits )
00746                 printf( "Recording clause %d: Cannot find variable %d in the temporary resolvent.\n", pFinal->Id, Var );
00747             if ( p->pResLits[v1] != lit_neg(pReason->pLits[0]) )
00748                 printf( "Recording clause %d: The resolved variable %d is in the wrong polarity.\n", pFinal->Id, Var );
00749             // remove this variable from the resolvent
00750             assert( lit_var(p->pResLits[v1]) == Var );
00751             p->nResLits--;
00752             for ( ; v1 < p->nResLits; v1++ )
00753                 p->pResLits[v1] = p->pResLits[v1+1];
00754             // add variables of the reason clause
00755             for ( v2 = 1; v2 < (int)pReason->nLits; v2++ )
00756             {
00757                 for ( v1 = 0; v1 < p->nResLits; v1++ )
00758                     if ( lit_var(p->pResLits[v1]) == lit_var(pReason->pLits[v2]) )
00759                         break;
00760                 // if it is a new variable, add it to the resolvent
00761                 if ( v1 == p->nResLits ) 
00762                 {
00763                     if ( p->nResLits == p->nResLitsAlloc )
00764                         printf( "Recording clause %d: Ran out of space for intermediate resolvent.\n, pFinal->Id" );
00765                     p->pResLits[ p->nResLits++ ] = pReason->pLits[v2];
00766                     continue;
00767                 }
00768                 // if the variable is the same, the literal should be the same too
00769                 if ( p->pResLits[v1] == pReason->pLits[v2] )
00770                     continue;
00771                 // the literal is different
00772                 printf( "Recording clause %d: Trying to resolve the clause with more than one opposite literal.\n", pFinal->Id );
00773             }
00774         }
00775 
00776 //        Vec_PtrPush( pFinal->pAntis, pReason );
00777     }
00778 
00779     // unmark all seen variables
00780 //    for ( i = p->nTrailSize - 1; i >= 0; i-- )
00781 //        p->pSeens[lit_var(p->pTrail[i])] = 0;
00782     // check that the literals are unmarked
00783 //    for ( i = p->nTrailSize - 1; i >= 0; i-- )
00784 //        assert( p->pSeens[lit_var(p->pTrail[i])] == 0 );
00785 
00786     // use the resulting clause to check the correctness of resolution
00787     if ( p->fProofVerif )
00788     {
00789         int v1, v2; 
00790         if ( fPrint )
00791             Pr_ManPrintResolvent( p->pResLits, p->nResLits );
00792         for ( v1 = 0; v1 < p->nResLits; v1++ )
00793         {
00794             for ( v2 = 0; v2 < (int)pFinal->nLits; v2++ )
00795                 if ( pFinal->pLits[v2] == p->pResLits[v1] )
00796                     break;
00797             if ( v2 < (int)pFinal->nLits )
00798                 continue;
00799             break;
00800         }
00801         if ( v1 < p->nResLits )
00802         {
00803             printf( "Recording clause %d: The final resolvent is wrong.\n", pFinal->Id );
00804             Pr_ManPrintClause( pConflict );
00805             Pr_ManPrintResolvent( p->pResLits, p->nResLits );
00806             Pr_ManPrintClause( pFinal );
00807         }
00808     }
00809 p->timeTrace += clock() - clk;
00810 
00811     // return the proof pointer 
00812     if ( p->nClausesA )
00813     {
00814         Pr_ManPrintInterOne( p, pFinal );
00815     }
00816     return p->Counter;
00817 }

int Pr_ManProofWrite ( Pr_Man_t p  ) 

Function*************************************************************

Synopsis [Records the proof.]

Description []

SideEffects []

SeeAlso []

Definition at line 1051 of file pr.c.

01052 {
01053     Pr_Cls_t * pClause;
01054     int RetValue = 1;
01055 
01056     // propagate root level assignments
01057     Pr_ManProcessRoots( p );
01058 
01059     // prepare the interpolant computation
01060     if ( p->nClausesA )
01061         Pr_ManPrepareInter( p );
01062 
01063     // construct proof for each clause
01064     // start the proof
01065     if ( p->fProofWrite )
01066         p->pManProof = fopen( "proof.cnf_", "w" );
01067     p->Counter = 0;
01068 
01069     // write the root clauses
01070     Pr_ManForEachClauseRoot( p, pClause )
01071         Pr_ManProofWriteOne( p, pClause );
01072 
01073     // consider each learned clause
01074     Pr_ManForEachClauseLearnt( p, pClause )
01075     {
01076         if ( !Pr_ManProofRecordOne( p, pClause ) )
01077         {
01078             RetValue = 0;
01079             break;
01080         }
01081     }
01082 
01083     if ( p->nClausesA )
01084     {
01085         printf( "Interpolant:  " );
01086     }
01087 
01088 
01089     // stop the proof
01090     if ( p->fProofWrite )
01091     {
01092         fclose( p->pManProof );
01093         p->pManProof = NULL;    
01094     }
01095     return RetValue;
01096 }

void Pr_ManProofWriteOne ( Pr_Man_t p,
Pr_Cls_t pClause 
)

Function*************************************************************

Synopsis [Writes one root clause into a file.]

Description []

SideEffects []

SeeAlso []

Definition at line 648 of file pr.c.

00649 {
00650     pClause->pProof = (void *)++p->Counter;
00651 
00652     if ( p->fProofWrite )
00653     {
00654         int v;
00655         fprintf( p->pManProof, "%d", (int)pClause->pProof );
00656         for ( v = 0; v < (int)pClause->nLits; v++ )
00657             fprintf( p->pManProof, " %d", lit_print(pClause->pLits[v]) );
00658         fprintf( p->pManProof, " 0 0\n" );
00659     }
00660 }

Pr_Cls_t* Pr_ManPropagate ( Pr_Man_t p,
int  Start 
)

Function*************************************************************

Synopsis [Propagate the current assignments.]

Description []

SideEffects []

SeeAlso []

Definition at line 578 of file pr.c.

00579 {
00580     Pr_Cls_t * pClause;
00581     int i;
00582     int clk = clock();
00583     for ( i = Start; i < p->nTrailSize; i++ )
00584     {
00585         pClause = Pr_ManPropagateOne( p, p->pTrail[i] );
00586         if ( pClause )
00587         {
00588 p->timeBcp += clock() - clk;
00589             return pClause;
00590         }
00591     }
00592 p->timeBcp += clock() - clk;
00593     return NULL;
00594 }

static Pr_Cls_t* Pr_ManPropagateOne ( Pr_Man_t p,
lit  Lit 
) [inline, static]

Function*************************************************************

Synopsis [Propagate one assignment.]

Description []

SideEffects []

SeeAlso []

Definition at line 509 of file pr.c.

00510 {
00511     Pr_Cls_t ** ppPrev, * pCur, * pTemp;
00512     lit LitF = lit_neg(Lit);
00513     int i;
00514     // iterate through the literals
00515     ppPrev = p->pWatches + Lit;
00516     for ( pCur = p->pWatches[Lit]; pCur; pCur = *ppPrev )
00517     {
00518         // make sure the false literal is in the second literal of the clause
00519         if ( pCur->pLits[0] == LitF )
00520         {
00521             pCur->pLits[0] = pCur->pLits[1];
00522             pCur->pLits[1] = LitF;
00523             pTemp = pCur->pNext0;
00524             pCur->pNext0 = pCur->pNext1;
00525             pCur->pNext1 = pTemp;
00526         }
00527         assert( pCur->pLits[1] == LitF );
00528 
00529         // if the first literal is true, the clause is satisfied
00530         if ( pCur->pLits[0] == p->pAssigns[lit_var(pCur->pLits[0])] )
00531         {
00532             ppPrev = &pCur->pNext1;
00533             continue;
00534         }
00535 
00536         // look for a new literal to watch
00537         for ( i = 2; i < (int)pCur->nLits; i++ )
00538         {
00539             // skip the case when the literal is false
00540             if ( lit_neg(pCur->pLits[i]) == p->pAssigns[lit_var(pCur->pLits[i])] )
00541                 continue;
00542             // the literal is either true or unassigned - watch it
00543             pCur->pLits[1] = pCur->pLits[i];
00544             pCur->pLits[i] = LitF;
00545             // remove this clause from the watch list of Lit
00546             *ppPrev = pCur->pNext1;
00547             // add this clause to the watch list of pCur->pLits[i] (now it is pCur->pLits[1])
00548             Pr_ManWatchClause( p, pCur, pCur->pLits[1] );
00549             break;
00550         }
00551         if ( i < (int)pCur->nLits ) // found new watch
00552             continue;
00553 
00554         // clause is unit - enqueue new implication
00555         if ( Pr_ManEnqueue(p, pCur->pLits[0], pCur) )
00556         {
00557             ppPrev = &pCur->pNext1;
00558             continue;
00559         }
00560 
00561         // conflict detected - return the conflict clause
00562         return pCur;
00563     }
00564     return NULL;
00565 }

void Pr_ManResize ( Pr_Man_t p,
int  nVarsNew 
) [static]

Function*************************************************************

Synopsis [Resize proof manager.]

Description []

SideEffects []

SeeAlso []

Definition at line 174 of file pr.c.

00175 {
00176     // check if resizing is needed
00177     if ( p->nVarsAlloc < nVarsNew )
00178     {
00179         int nVarsAllocOld = p->nVarsAlloc;
00180         // find the new size
00181         if ( p->nVarsAlloc == 0 )
00182             p->nVarsAlloc = 1;
00183         while ( p->nVarsAlloc < nVarsNew ) 
00184             p->nVarsAlloc *= 2;
00185         // resize the arrays
00186         p->pTrail    = (lit *)      realloc( p->pTrail,    sizeof(lit) * p->nVarsAlloc );
00187         p->pAssigns  = (lit *)      realloc( p->pAssigns,  sizeof(lit) * p->nVarsAlloc );
00188         p->pSeens    = (char *)     realloc( p->pSeens,    sizeof(char) * p->nVarsAlloc );
00189         p->pVarTypes = (char *)     realloc( p->pVarTypes, sizeof(char) * p->nVarsAlloc );
00190         p->pReasons  = (Pr_Cls_t **)realloc( p->pReasons,  sizeof(Pr_Cls_t *) * p->nVarsAlloc );
00191         p->pWatches  = (Pr_Cls_t **)realloc( p->pWatches,  sizeof(Pr_Cls_t *) * p->nVarsAlloc*2 );
00192         // clean the free space
00193         memset( p->pAssigns  + nVarsAllocOld, 0xff, sizeof(lit) * (p->nVarsAlloc - nVarsAllocOld) );
00194         memset( p->pSeens    + nVarsAllocOld, 0, sizeof(char) * (p->nVarsAlloc - nVarsAllocOld) );
00195         memset( p->pVarTypes + nVarsAllocOld, 0, sizeof(char) * (p->nVarsAlloc - nVarsAllocOld) );
00196         memset( p->pReasons  + nVarsAllocOld, 0, sizeof(Pr_Cls_t *) * (p->nVarsAlloc - nVarsAllocOld) );
00197         memset( p->pWatches  + nVarsAllocOld, 0, sizeof(Pr_Cls_t *) * (p->nVarsAlloc - nVarsAllocOld)*2 );
00198     }
00199     // adjust the number of variables
00200     if ( p->nVars < nVarsNew )
00201         p->nVars = nVarsNew;
00202 }

static void Pr_ManWatchClause ( Pr_Man_t p,
Pr_Cls_t pClause,
lit  Lit 
) [inline, static]

Function*************************************************************

Synopsis [Adds one clause to the watcher list.]

Description []

SideEffects []

SeeAlso []

Definition at line 245 of file pr.c.

00246 {
00247     assert( lit_check(Lit, p->nVars) );
00248     if ( pClause->pLits[0] == Lit )
00249         pClause->pNext0 = p->pWatches[lit_neg(Lit)];  
00250     else
00251     {
00252         assert( pClause->pLits[1] == Lit );
00253         pClause->pNext1 = p->pWatches[lit_neg(Lit)];  
00254     }
00255     p->pWatches[lit_neg(Lit)] = pClause;
00256 }

static lit toLit ( int  v  )  [inline, static]

Definition at line 102 of file pr.c.

00102 { return v + v;  }

static lit toLitCond ( int  v,
int  c 
) [inline, static]

Definition at line 103 of file pr.c.

00103 { return v + v + (c != 0); }


Variable Documentation

const lit LIT_UNDEF = 0xffffffff [static]

Definition at line 99 of file pr.c.


Generated on Tue Jan 5 12:19:40 2010 for abc70930 by  doxygen 1.6.1