#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#include "pr.h"
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_t * | Pr_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_t * | Pr_ManPropagateOne (Pr_Man_t *p, lit Lit) |
Pr_Cls_t * | Pr_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_t * | Pr_ManProofRead (char *pFileName) |
int | Pr_ManProofTest (char *pFileName) |
Variables | |
static const lit | LIT_UNDEF = 0xffffffff |
#define Pr_ManForEachClause | ( | p, | |||
pCls | ) | for( pCls = p->pHead; pCls; pCls = pCls->pNext ) |
#define Pr_ManForEachClauseLearnt | ( | p, | |||
pCls | ) | for( pCls = p->pLearnt; pCls; pCls = pCls->pNext ) |
#define Pr_ManForEachClauseRoot | ( | p, | |||
pCls | ) | for( pCls = p->pHead; pCls != p->pLearnt; pCls = pCls->pNext ) |
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 [
] DECLARATIONS ///
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] |
static int lit_print | ( | lit | l | ) | [inline, static] |
static lit lit_read | ( | int | s | ) | [inline, static] |
static int lit_sign | ( | lit | l | ) | [inline, static] |
static int lit_var | ( | lit | l | ) | [inline, static] |
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 }
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 []
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 []
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 }
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 }
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 }
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 }
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 }
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 }
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] |
static lit toLitCond | ( | int | v, | |
int | c | |||
) | [inline, static] |