00001
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <assert.h>
00025 #include <time.h>
00026
00027 #include "pr.h"
00028
00032
00033 typedef unsigned lit;
00034
00035 typedef struct Pr_Cls_t_ Pr_Cls_t;
00036 struct Pr_Cls_t_
00037 {
00038 unsigned uTruth;
00039 void * pProof;
00040
00041 Pr_Cls_t * pNext;
00042 Pr_Cls_t * pNext0;
00043 Pr_Cls_t * pNext1;
00044 int Id;
00045 unsigned fA : 1;
00046 unsigned fRoot : 1;
00047 unsigned fVisit : 1;
00048 unsigned nLits : 24;
00049 lit pLits[0];
00050 };
00051
00052 struct Pr_Man_t_
00053 {
00054
00055 int fProofWrite;
00056 int fProofVerif;
00057 int nVars;
00058 int nVarsAB;
00059 int nRoots;
00060 int nClauses;
00061 int nClausesA;
00062 Pr_Cls_t * pHead;
00063 Pr_Cls_t * pTail;
00064 Pr_Cls_t * pLearnt;
00065 Pr_Cls_t * pEmpty;
00066
00067 int nRootSize;
00068 int nTrailSize;
00069 lit * pTrail;
00070 lit * pAssigns;
00071 char * pSeens;
00072 char * pVarTypes;
00073 Pr_Cls_t ** pReasons;
00074 Pr_Cls_t ** pWatches;
00075 int nVarsAlloc;
00076
00077 void * pManProof;
00078 int Counter;
00079
00080 int nChunkSize;
00081 int nChunkUsed;
00082 char * pChunkLast;
00083
00084 lit * pResLits;
00085 int nResLits;
00086 int nResLitsAlloc;
00087
00088 int timeBcp;
00089 int timeTrace;
00090 int timeRead;
00091 int timeTotal;
00092 };
00093
00094 #ifndef PRT
00095 #define PRT(a,t) printf("%s = ", (a)); printf("%6.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC))
00096 #endif
00097
00098
00099 static const lit LIT_UNDEF = 0xffffffff;
00100
00101
00102 static inline lit toLit (int v) { return v + v; }
00103 static inline lit toLitCond(int v, int c) { return v + v + (c != 0); }
00104 static inline lit lit_neg (lit l) { return l ^ 1; }
00105 static inline int lit_var (lit l) { return l >> 1; }
00106 static inline int lit_sign (lit l) { return l & 1; }
00107 static inline int lit_print(lit l) { return lit_sign(l)? -lit_var(l)-1 : lit_var(l)+1; }
00108 static inline lit lit_read (int s) { return s > 0 ? toLit(s-1) : lit_neg(toLit(-s-1)); }
00109 static inline int lit_check(lit l, int n) { return l >= 0 && lit_var(l) < n; }
00110
00111
00112 #define Pr_ManForEachClause( p, pCls ) for( pCls = p->pHead; pCls; pCls = pCls->pNext )
00113 #define Pr_ManForEachClauseRoot( p, pCls ) for( pCls = p->pHead; pCls != p->pLearnt; pCls = pCls->pNext )
00114 #define Pr_ManForEachClauseLearnt( p, pCls ) for( pCls = p->pLearnt; pCls; pCls = pCls->pNext )
00115
00116
00117 static char * Pr_ManMemoryFetch( Pr_Man_t * p, int nBytes );
00118 static void Pr_ManMemoryStop( Pr_Man_t * p );
00119 static void Pr_ManResize( Pr_Man_t * p, int nVarsNew );
00120
00121
00122 extern Pr_Man_t * Pr_ManAlloc( int nVarsAlloc );
00123 extern void Pr_ManFree( Pr_Man_t * p );
00124 extern int Pr_ManAddClause( Pr_Man_t * p, lit * pBeg, lit * pEnd, int fRoot, int fClauseA );
00125 extern int Pr_ManProofWrite( Pr_Man_t * p );
00126
00130
00142 Pr_Man_t * Pr_ManAlloc( int nVarsAlloc )
00143 {
00144 Pr_Man_t * p;
00145
00146 p = (Pr_Man_t *)malloc( sizeof(Pr_Man_t) );
00147 memset( p, 0, sizeof(Pr_Man_t) );
00148
00149 Pr_ManResize( p, nVarsAlloc? nVarsAlloc : 256 );
00150
00151 p->nVars = 0;
00152
00153 p->nChunkSize = (1<<16);
00154
00155 p->nResLitsAlloc = (1<<16);
00156 p->pResLits = malloc( sizeof(lit) * p->nResLitsAlloc );
00157
00158 p->fProofWrite = 0;
00159 p->fProofVerif = 0;
00160 return p;
00161 }
00162
00174 void Pr_ManResize( Pr_Man_t * p, int nVarsNew )
00175 {
00176
00177 if ( p->nVarsAlloc < nVarsNew )
00178 {
00179 int nVarsAllocOld = p->nVarsAlloc;
00180
00181 if ( p->nVarsAlloc == 0 )
00182 p->nVarsAlloc = 1;
00183 while ( p->nVarsAlloc < nVarsNew )
00184 p->nVarsAlloc *= 2;
00185
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
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
00200 if ( p->nVars < nVarsNew )
00201 p->nVars = nVarsNew;
00202 }
00203
00215 void Pr_ManFree( Pr_Man_t * p )
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 }
00233
00245 static inline void Pr_ManWatchClause( Pr_Man_t * p, Pr_Cls_t * pClause, lit Lit )
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 }
00257
00269 int Pr_ManAddClause( Pr_Man_t * p, lit * pBeg, lit * pEnd, int fRoot, int fClauseA )
00270 {
00271 Pr_Cls_t * pClause;
00272 lit Lit, * i, * j;
00273 int nSize, VarMax;
00274
00275
00276 if ( pBeg < pEnd )
00277 {
00278
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
00289 for ( i = pBeg + 1; i < pEnd; i++ )
00290 assert( lit_var(*(i-1)) != lit_var(*i) );
00291
00292 Pr_ManResize( p, VarMax+1 );
00293 }
00294
00295
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
00301 assert( !fClauseA || fRoot );
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
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
00322 if ( p->pLearnt == NULL && !pClause->fRoot )
00323 p->pLearnt = pClause;
00324
00325
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 }
00334
00346 char * Pr_ManMemoryFetch( Pr_Man_t * p, int nBytes )
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 }
00360
00372 void Pr_ManMemoryStop( Pr_Man_t * p )
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 }
00381
00393 int Pr_ManMemoryReport( Pr_Man_t * p )
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 }
00404
00416 void Extra_PrintBinary_( FILE * pFile, unsigned Sign[], int nBits )
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 }
00428
00440 void Pr_ManPrintInterOne( Pr_Man_t * p, Pr_Cls_t * pClause )
00441 {
00442 printf( "Clause %2d : ", pClause->Id );
00443 Extra_PrintBinary_( stdout, &pClause->uTruth, (1 << p->nVarsAB) );
00444 printf( "\n" );
00445 }
00446
00447
00448
00460 static inline int Pr_ManEnqueue( Pr_Man_t * p, lit Lit, Pr_Cls_t * pReason )
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
00469 return 1;
00470 }
00471
00483 static inline void Pr_ManCancelUntil( Pr_Man_t * p, int Level )
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
00494 }
00495 p->nTrailSize = Level;
00496 }
00497
00509 static inline Pr_Cls_t * Pr_ManPropagateOne( Pr_Man_t * p, lit Lit )
00510 {
00511 Pr_Cls_t ** ppPrev, * pCur, * pTemp;
00512 lit LitF = lit_neg(Lit);
00513 int i;
00514
00515 ppPrev = p->pWatches + Lit;
00516 for ( pCur = p->pWatches[Lit]; pCur; pCur = *ppPrev )
00517 {
00518
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
00530 if ( pCur->pLits[0] == p->pAssigns[lit_var(pCur->pLits[0])] )
00531 {
00532 ppPrev = &pCur->pNext1;
00533 continue;
00534 }
00535
00536
00537 for ( i = 2; i < (int)pCur->nLits; i++ )
00538 {
00539
00540 if ( lit_neg(pCur->pLits[i]) == p->pAssigns[lit_var(pCur->pLits[i])] )
00541 continue;
00542
00543 pCur->pLits[1] = pCur->pLits[i];
00544 pCur->pLits[i] = LitF;
00545
00546 *ppPrev = pCur->pNext1;
00547
00548 Pr_ManWatchClause( p, pCur, pCur->pLits[1] );
00549 break;
00550 }
00551 if ( i < (int)pCur->nLits )
00552 continue;
00553
00554
00555 if ( Pr_ManEnqueue(p, pCur->pLits[0], pCur) )
00556 {
00557 ppPrev = &pCur->pNext1;
00558 continue;
00559 }
00560
00561
00562 return pCur;
00563 }
00564 return NULL;
00565 }
00566
00578 Pr_Cls_t * Pr_ManPropagate( Pr_Man_t * p, int Start )
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 }
00595
00596
00608 void Pr_ManPrintClause( Pr_Cls_t * pClause )
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 }
00616
00628 void Pr_ManPrintResolvent( lit * pResLits, int nResLits )
00629 {
00630 int i;
00631 printf( "Resolvent: {" );
00632 for ( i = 0; i < nResLits; i++ )
00633 printf( " %d", pResLits[i] );
00634 printf( " }\n" );
00635 }
00636
00648 void Pr_ManProofWriteOne( Pr_Man_t * p, Pr_Cls_t * pClause )
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 }
00661
00673 int Pr_ManProofTraceOne( Pr_Man_t * p, Pr_Cls_t * pConflict, Pr_Cls_t * pFinal )
00674 {
00675 Pr_Cls_t * pReason;
00676 int i, v, Var, PrevId;
00677 int fPrint = 0;
00678 int clk = clock();
00679
00680
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
00689 for ( v = 0; v < (int)pConflict->nLits; v++ )
00690 p->pSeens[lit_var(pConflict->pLits[v])] = 1;
00691
00692
00693
00694
00695
00696 if ( p->nClausesA )
00697 pFinal->uTruth = pConflict->uTruth;
00698
00699
00700 PrevId = (int)pConflict->pProof;
00701 for ( i = p->nTrailSize - 1; i >= 0; i-- )
00702 {
00703
00704 Var = lit_var(p->pTrail[i]);
00705 if ( !p->pSeens[Var] )
00706 continue;
00707 p->pSeens[Var] = 0;
00708
00709
00710 pReason = p->pReasons[Var];
00711 if ( pReason == NULL )
00712 continue;
00713 assert( p->pTrail[i] == pReason->pLits[0] );
00714
00715
00716 for ( v = 1; v < (int)pReason->nLits; v++ )
00717 p->pSeens[lit_var(pReason->pLits[v])] = 1;
00718
00719
00720
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 )
00730 pFinal->uTruth |= pReason->uTruth;
00731 else
00732 pFinal->uTruth &= pReason->uTruth;
00733 }
00734
00735
00736 if ( p->fProofVerif )
00737 {
00738 int v1, v2;
00739 if ( fPrint )
00740 Pr_ManPrintResolvent( p->pResLits, p->nResLits );
00741
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
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
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
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
00769 if ( p->pResLits[v1] == pReason->pLits[v2] )
00770 continue;
00771
00772 printf( "Recording clause %d: Trying to resolve the clause with more than one opposite literal.\n", pFinal->Id );
00773 }
00774 }
00775
00776
00777 }
00778
00779
00780
00781
00782
00783
00784
00785
00786
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
00812 if ( p->nClausesA )
00813 {
00814 Pr_ManPrintInterOne( p, pFinal );
00815 }
00816 return p->Counter;
00817 }
00818
00830 int Pr_ManProofRecordOne( Pr_Man_t * p, Pr_Cls_t * pClause )
00831 {
00832 Pr_Cls_t * pConflict;
00833 int i;
00834
00835
00836 assert( pClause->nLits > 0 );
00837 if ( pClause->nLits == 0 )
00838 printf( "Error: Empty clause is attempted.\n" );
00839
00840
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 );
00847 return 0;
00848 }
00849
00850
00851 pConflict = Pr_ManPropagate( p, p->nRootSize );
00852 if ( pConflict == NULL )
00853 {
00854 assert( 0 );
00855 return 0;
00856 }
00857
00858
00859 pClause->pProof = (void *)Pr_ManProofTraceOne( p, pConflict, pClause );
00860
00861
00862 Pr_ManCancelUntil( p, p->nRootSize );
00863
00864
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
00874 if ( !Pr_ManEnqueue( p, pClause->pLits[0], pClause ) )
00875 {
00876 assert( 0 );
00877 return 0;
00878 }
00879
00880
00881 pConflict = Pr_ManPropagate( p, p->nRootSize );
00882 if ( pConflict )
00883 {
00884
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
00891 p->nRootSize = p->nTrailSize;
00892 return 1;
00893 }
00894
00906 int Pr_ManProcessRoots( Pr_Man_t * p )
00907 {
00908 Pr_Cls_t * pClause;
00909 int Counter;
00910
00911
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
00922 assert( p->pTail->nLits == 0 );
00923
00924
00925 p->nTrailSize = 0;
00926 Pr_ManForEachClauseRoot( p, pClause )
00927 {
00928
00929 if ( pClause->nLits > 1 )
00930 {
00931 Pr_ManWatchClause( p, pClause, pClause->pLits[0] );
00932 Pr_ManWatchClause( p, pClause, pClause->pLits[1] );
00933 }
00934
00935 if ( pClause->nLits != 1 )
00936 continue;
00937
00938 assert( lit_check(pClause->pLits[0], p->nVars) );
00939 if ( !Pr_ManEnqueue( p, pClause->pLits[0], pClause ) )
00940 {
00941
00942 printf( "Pr_ManProcessRoots(): Detected a root-level conflict\n" );
00943 assert( 0 );
00944 return 0;
00945 }
00946 }
00947
00948
00949 pClause = Pr_ManPropagate( p, 0 );
00950 if ( pClause )
00951 {
00952
00953 printf( "Pr_ManProcessRoots(): Detected a root-level conflict\n" );
00954 assert( 0 );
00955 return 0;
00956 }
00957
00958
00959 p->nRootSize = p->nTrailSize;
00960 return 1;
00961 }
00962
00974 void Pr_ManPrepareInter( Pr_Man_t * p )
00975 {
00976 unsigned uTruths[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
00977 Pr_Cls_t * pClause;
00978 int Var, v;
00979
00980
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
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 )
00999 {
01000
01001 p->nVarsAB++;
01002 p->pVarTypes[Var] = -1;
01003 }
01004 }
01005 }
01006
01007
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
01015 Pr_ManForEachClauseRoot( p, pClause )
01016 {
01017 if ( !pClause->fA )
01018 {
01019 pClause->uTruth = ~0;
01020 Pr_ManPrintInterOne( p, pClause );
01021 continue;
01022 }
01023
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 )
01029 {
01030 if ( lit_sign(pClause->pLits[v]) )
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 }
01039
01051 int Pr_ManProofWrite( Pr_Man_t * p )
01052 {
01053 Pr_Cls_t * pClause;
01054 int RetValue = 1;
01055
01056
01057 Pr_ManProcessRoots( p );
01058
01059
01060 if ( p->nClausesA )
01061 Pr_ManPrepareInter( p );
01062
01063
01064
01065 if ( p->fProofWrite )
01066 p->pManProof = fopen( "proof.cnf_", "w" );
01067 p->Counter = 0;
01068
01069
01070 Pr_ManForEachClauseRoot( p, pClause )
01071 Pr_ManProofWriteOne( p, pClause );
01072
01073
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
01090 if ( p->fProofWrite )
01091 {
01092 fclose( p->pManProof );
01093 p->pManProof = NULL;
01094 }
01095 return RetValue;
01096 }
01097
01109 Pr_Man_t * Pr_ManProofRead( char * pFileName )
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
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
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
01146 for ( pCur = pBuffer; *pCur; pCur++ )
01147 if ( !(*pCur == ' ' || *pCur == '\t' || *pCur == '\r' || *pCur == '\n') )
01148 break;
01149 if ( *pCur == 0 )
01150 continue;
01151
01152 nNumbers = 0;
01153 pCur = pBuffer;
01154 while ( *pCur )
01155 {
01156
01157 for ( ; *pCur && *pCur == ' '; pCur++ );
01158
01159 Temp = 0;
01160 sscanf( pCur, "%d", &Temp );
01161 if ( Temp == 0 )
01162 break;
01163 pArray[ nNumbers++ ] = lit_read( Temp );
01164
01165 for ( ; *pCur && *pCur != ' '; pCur++ );
01166 }
01167
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
01174 Counter++;
01175 }
01176
01177 if ( Counter != nClauses )
01178 printf( "Expected %d clauses but read %d.\n", nClauses, Counter );
01179
01180
01181 if ( pArray ) free( pArray );
01182 if ( pBuffer ) free( pBuffer );
01183 fclose( pFile );
01184 return p;
01185 }
01186
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01227 int Pr_ManProofTest( char * pFileName )
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
01241
01242
01243
01244
01245
01246
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 }
01257
01258
01262
01263