00001
00021 #include "msatInt.h"
00022
00026
00027 struct Msat_Clause_t_
00028 {
00029 int Num;
00030 unsigned fLearned : 1;
00031 unsigned fMark : 1;
00032 unsigned fTypeA : 1;
00033 unsigned nSize : 14;
00034 unsigned nSizeAlloc : 15;
00035 Msat_Lit_t pData[0];
00036 };
00037
00041
00055 bool Msat_ClauseCreate( Msat_Solver_t * p, Msat_IntVec_t * vLits, bool fLearned, Msat_Clause_t ** pClause_out )
00056 {
00057 int * pAssigns = Msat_SolverReadAssignsArray(p);
00058 Msat_ClauseVec_t ** pvWatched;
00059 Msat_Clause_t * pC;
00060 int * pLits;
00061 int nLits, i, j;
00062 int nBytes;
00063 Msat_Var_t Var;
00064 bool Sign;
00065
00066 *pClause_out = NULL;
00067
00068 nLits = Msat_IntVecReadSize(vLits);
00069 pLits = Msat_IntVecReadArray(vLits);
00070
00071 if ( !fLearned )
00072 {
00073 int * pSeen = Msat_SolverReadSeenArray( p );
00074 int nSeenId;
00075 assert( Msat_SolverReadDecisionLevel(p) == 0 );
00076
00077
00078 Msat_IntVecSort( vLits, 0 );
00079
00080 nSeenId = Msat_SolverIncrementSeenId( p );
00081 nSeenId = Msat_SolverIncrementSeenId( p );
00082
00083
00084
00085
00086
00087
00088
00089 for ( i = j = 0; i < nLits; i++ ) {
00090
00091 Var = MSAT_LIT2VAR(pLits[i]);
00092 Sign = MSAT_LITSIGN(pLits[i]);
00093
00094 if ( pSeen[Var] >= nSeenId - 1 )
00095 {
00096 if ( (pSeen[Var] != nSeenId) == Sign )
00097 continue;
00098 return 1;
00099 }
00100
00101 pSeen[Var] = nSeenId - !Sign;
00102
00103
00104 if ( pAssigns[Var] != MSAT_VAR_UNASSIGNED )
00105 {
00106 if ( pAssigns[Var] == pLits[i] )
00107 return 1;
00108
00109 continue;
00110 }
00111
00112 pLits[j++] = pLits[i];
00113 }
00114 Msat_IntVecShrink( vLits, j );
00115 nLits = j;
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 }
00145
00146 if ( nLits == 0 )
00147 return 0;
00148 if ( nLits == 1 )
00149 return Msat_SolverEnqueue( p, pLits[0], NULL );
00150
00151
00152
00153 nBytes = sizeof(unsigned)*(nLits + 2 + (int)fLearned);
00154 #ifdef USE_SYSTEM_MEMORY_MANAGEMENT
00155 pC = (Msat_Clause_t *)ALLOC( char, nBytes );
00156 #else
00157 pC = (Msat_Clause_t *)Msat_MmStepEntryFetch( Msat_SolverReadMem(p), nBytes );
00158 #endif
00159 pC->Num = p->nClauses++;
00160 pC->fTypeA = 0;
00161 pC->fMark = 0;
00162 pC->fLearned = fLearned;
00163 pC->nSize = nLits;
00164 pC->nSizeAlloc = nBytes;
00165 memcpy( pC->pData, pLits, sizeof(int)*nLits );
00166
00167
00168 if ( fLearned )
00169 {
00170 int * pLevel = Msat_SolverReadDecisionLevelArray( p );
00171 int iLevelMax, iLevelCur, iLitMax;
00172
00173
00174 iLitMax = 1;
00175 iLevelMax = pLevel[ MSAT_LIT2VAR(pLits[1]) ];
00176 for ( i = 2; i < nLits; i++ )
00177 {
00178 iLevelCur = pLevel[ MSAT_LIT2VAR(pLits[i]) ];
00179 assert( iLevelCur != -1 );
00180 if ( iLevelMax < iLevelCur )
00181
00182
00183 iLevelMax = iLevelCur, iLitMax = i;
00184 }
00185 pC->pData[1] = pLits[iLitMax];
00186 pC->pData[iLitMax] = pLits[1];
00187
00188
00189
00190 Msat_ClauseWriteActivity( pC, 0.0 );
00191 Msat_SolverClaBumpActivity( p, pC );
00192
00193 for ( i = 0; i < nLits; i++ )
00194 {
00195 Msat_SolverVarBumpActivity( p, pLits[i] );
00196
00197
00198 }
00199 }
00200
00201
00202 pvWatched = Msat_SolverReadWatchedArray( p );
00203 Msat_ClauseVecPush( pvWatched[ MSAT_LITNOT(pC->pData[0]) ], pC );
00204 Msat_ClauseVecPush( pvWatched[ MSAT_LITNOT(pC->pData[1]) ], pC );
00205 *pClause_out = pC;
00206 return 1;
00207 }
00208
00220 void Msat_ClauseFree( Msat_Solver_t * p, Msat_Clause_t * pC, bool fRemoveWatched )
00221 {
00222 if ( fRemoveWatched )
00223 {
00224 Msat_Lit_t Lit;
00225 Msat_ClauseVec_t ** pvWatched;
00226 pvWatched = Msat_SolverReadWatchedArray( p );
00227 Lit = MSAT_LITNOT( pC->pData[0] );
00228 Msat_ClauseRemoveWatch( pvWatched[Lit], pC );
00229 Lit = MSAT_LITNOT( pC->pData[1] );
00230 Msat_ClauseRemoveWatch( pvWatched[Lit], pC );
00231 }
00232
00233 #ifdef USE_SYSTEM_MEMORY_MANAGEMENT
00234 free( pC );
00235 #else
00236 Msat_MmStepEntryRecycle( Msat_SolverReadMem(p), (char *)pC, pC->nSizeAlloc );
00237 #endif
00238
00239 }
00240
00252 bool Msat_ClauseReadLearned( Msat_Clause_t * pC ) { return pC->fLearned; }
00253 int Msat_ClauseReadSize( Msat_Clause_t * pC ) { return pC->nSize; }
00254 int * Msat_ClauseReadLits( Msat_Clause_t * pC ) { return pC->pData; }
00255 bool Msat_ClauseReadMark( Msat_Clause_t * pC ) { return pC->fMark; }
00256 int Msat_ClauseReadNum( Msat_Clause_t * pC ) { return pC->Num; }
00257 bool Msat_ClauseReadTypeA( Msat_Clause_t * pC ) { return pC->fTypeA; }
00258
00259 void Msat_ClauseSetMark( Msat_Clause_t * pC, bool fMark ) { pC->fMark = fMark; }
00260 void Msat_ClauseSetNum( Msat_Clause_t * pC, int Num ) { pC->Num = Num; }
00261 void Msat_ClauseSetTypeA( Msat_Clause_t * pC, bool fTypeA ) { pC->fTypeA = fTypeA; }
00262
00275 bool Msat_ClauseIsLocked( Msat_Solver_t * p, Msat_Clause_t * pC )
00276 {
00277 Msat_Clause_t ** pReasons = Msat_SolverReadReasonArray( p );
00278 return (bool)(pReasons[MSAT_LIT2VAR(pC->pData[0])] == pC);
00279 }
00280
00292 float Msat_ClauseReadActivity( Msat_Clause_t * pC )
00293 {
00294 return *((float *)(pC->pData + pC->nSize));
00295 }
00296
00308 void Msat_ClauseWriteActivity( Msat_Clause_t * pC, float Num )
00309 {
00310 *((float *)(pC->pData + pC->nSize)) = Num;
00311 }
00312
00329 bool Msat_ClausePropagate( Msat_Clause_t * pC, Msat_Lit_t Lit, int * pAssigns, Msat_Lit_t * pLit_out )
00330 {
00331
00332 Msat_Lit_t LitF = MSAT_LITNOT(Lit);
00333 if ( pC->pData[0] == LitF )
00334 pC->pData[0] = pC->pData[1], pC->pData[1] = LitF;
00335 assert( pC->pData[1] == LitF );
00336
00337 if ( pAssigns[MSAT_LIT2VAR(pC->pData[0])] == pC->pData[0] )
00338 return 1;
00339
00340 if ( pC->nSize > 2 )
00341 {
00342 int i;
00343 for ( i = 2; i < (int)pC->nSize; i++ )
00344 if ( pAssigns[MSAT_LIT2VAR(pC->pData[i])] != MSAT_LITNOT(pC->pData[i]) )
00345 {
00346 pC->pData[1] = pC->pData[i], pC->pData[i] = LitF;
00347 *pLit_out = MSAT_LITNOT(pC->pData[1]);
00348 return 1;
00349 }
00350 }
00351
00352 *pLit_out = pC->pData[0];
00353 return 0;
00354 }
00355
00368 bool Msat_ClauseSimplify( Msat_Clause_t * pC, int * pAssigns )
00369 {
00370 Msat_Var_t Var;
00371 int i, j;
00372 for ( i = j = 0; i < (int)pC->nSize; i++ )
00373 {
00374 Var = MSAT_LIT2VAR(pC->pData[i]);
00375 if ( pAssigns[Var] == MSAT_VAR_UNASSIGNED )
00376 {
00377 pC->pData[j++] = pC->pData[i];
00378 continue;
00379 }
00380 if ( pAssigns[Var] == pC->pData[i] )
00381 return 1;
00382
00383
00384 assert( i >= 2 );
00385 }
00386
00387 if ( j < (int)pC->nSize )
00388 {
00389 float Activ = Msat_ClauseReadActivity(pC);
00390 pC->nSize = j;
00391 Msat_ClauseWriteActivity(pC, Activ);
00392 }
00393 return 0;
00394 }
00395
00412 void Msat_ClauseCalcReason( Msat_Solver_t * p, Msat_Clause_t * pC, Msat_Lit_t Lit, Msat_IntVec_t * vLits_out )
00413 {
00414 int i;
00415
00416 Msat_IntVecClear( vLits_out );
00417 assert( Lit == MSAT_LIT_UNASSIGNED || Lit == pC->pData[0] );
00418 for ( i = (Lit != MSAT_LIT_UNASSIGNED); i < (int)pC->nSize; i++ )
00419 {
00420 assert( Msat_SolverReadAssignsArray(p)[MSAT_LIT2VAR(pC->pData[i])] == MSAT_LITNOT(pC->pData[i]) );
00421 Msat_IntVecPush( vLits_out, MSAT_LITNOT(pC->pData[i]) );
00422 }
00423 if ( pC->fLearned )
00424 Msat_SolverClaBumpActivity( p, pC );
00425 }
00426
00438 void Msat_ClauseRemoveWatch( Msat_ClauseVec_t * vClauses, Msat_Clause_t * pC )
00439 {
00440 Msat_Clause_t ** pClauses;
00441 int nClauses, i;
00442 nClauses = Msat_ClauseVecReadSize( vClauses );
00443 pClauses = Msat_ClauseVecReadArray( vClauses );
00444 for ( i = 0; pClauses[i] != pC; i++ )
00445 assert( i < nClauses );
00446 for ( ; i < nClauses - 1; i++ )
00447 pClauses[i] = pClauses[i+1];
00448 Msat_ClauseVecPop( vClauses );
00449 }
00450
00462 void Msat_ClausePrint( Msat_Clause_t * pC )
00463 {
00464 int i;
00465 if ( pC == NULL )
00466 printf( "NULL pointer" );
00467 else
00468 {
00469 if ( pC->fLearned )
00470 printf( "Act = %.4f ", Msat_ClauseReadActivity(pC) );
00471 for ( i = 0; i < (int)pC->nSize; i++ )
00472 printf( " %s%d", ((pC->pData[i]&1)? "-": ""), pC->pData[i]/2 + 1 );
00473 }
00474 printf( "\n" );
00475 }
00476
00488 void Msat_ClauseWriteDimacs( FILE * pFile, Msat_Clause_t * pC, bool fIncrement )
00489 {
00490 int i;
00491 for ( i = 0; i < (int)pC->nSize; i++ )
00492 fprintf( pFile, "%s%d ", ((pC->pData[i]&1)? "-": ""), pC->pData[i]/2 + (int)(fIncrement>0) );
00493 if ( fIncrement )
00494 fprintf( pFile, "0" );
00495 fprintf( pFile, "\n" );
00496 }
00497
00509 void Msat_ClausePrintSymbols( Msat_Clause_t * pC )
00510 {
00511 int i;
00512 if ( pC == NULL )
00513 printf( "NULL pointer" );
00514 else
00515 {
00516
00517
00518 for ( i = 0; i < (int)pC->nSize; i++ )
00519 printf(" "L_LIT, L_lit(pC->pData[i]));
00520 }
00521 printf( "\n" );
00522 }
00523
00524
00528
00529