00001
00021 #include "msatInt.h"
00022
00023
00024
00025
00026
00027
00028
00032
00033 typedef struct Msat_OrderVar_t_ Msat_OrderVar_t;
00034 typedef struct Msat_OrderRing_t_ Msat_OrderRing_t;
00035
00036
00037 struct Msat_OrderVar_t_
00038 {
00039 Msat_OrderVar_t * pNext;
00040 Msat_OrderVar_t * pPrev;
00041 int Num;
00042 };
00043
00044
00045 struct Msat_OrderRing_t_
00046 {
00047 Msat_OrderVar_t * pRoot;
00048 int nItems;
00049 };
00050
00051
00052 struct Msat_Order_t_
00053 {
00054 Msat_Solver_t * pSat;
00055 Msat_OrderVar_t * pVars;
00056 int nVarsAlloc;
00057 Msat_OrderRing_t rVars;
00058 };
00059
00060
00061
00062
00063
00064
00065
00066 #define Msat_OrderVarIsInBoundary( p, i ) ((p)->pVars[i].pNext)
00067 #define Msat_OrderVarIsAssigned( p, i ) ((p)->pSat->pAssigns[i] != MSAT_VAR_UNASSIGNED)
00068 #define Msat_OrderVarIsUsedInCone( p, i ) ((p)->pSat->vVarsUsed->pArray[i])
00069
00070
00071 #define Msat_OrderRingForEachEntry( pRing, pVar, pNext ) \
00072 for ( pVar = pRing, \
00073 pNext = pVar? pVar->pNext : NULL; \
00074 pVar; \
00075 pVar = (pNext != pRing)? pNext : NULL, \
00076 pNext = pVar? pVar->pNext : NULL )
00077
00078 static void Msat_OrderRingAddLast( Msat_OrderRing_t * pRing, Msat_OrderVar_t * pVar );
00079 static void Msat_OrderRingRemove( Msat_OrderRing_t * pRing, Msat_OrderVar_t * pVar );
00080
00081 extern int timeSelect;
00082 extern int timeAssign;
00083
00087
00099 Msat_Order_t * Msat_OrderAlloc( Msat_Solver_t * pSat )
00100 {
00101 Msat_Order_t * p;
00102 p = ALLOC( Msat_Order_t, 1 );
00103 memset( p, 0, sizeof(Msat_Order_t) );
00104 p->pSat = pSat;
00105 Msat_OrderSetBounds( p, pSat->nVarsAlloc );
00106 return p;
00107 }
00108
00120 void Msat_OrderSetBounds( Msat_Order_t * p, int nVarsMax )
00121 {
00122 int i;
00123
00124 if ( p->nVarsAlloc < nVarsMax )
00125 {
00126 p->pVars = REALLOC( Msat_OrderVar_t, p->pVars, nVarsMax );
00127 for ( i = p->nVarsAlloc; i < nVarsMax; i++ )
00128 {
00129 p->pVars[i].pNext = p->pVars[i].pPrev = NULL;
00130 p->pVars[i].Num = i;
00131 }
00132 p->nVarsAlloc = nVarsMax;
00133 }
00134 }
00135
00147 void Msat_OrderClean( Msat_Order_t * p, Msat_IntVec_t * vCone )
00148 {
00149 Msat_OrderVar_t * pVar, * pNext;
00150
00151 Msat_OrderRingForEachEntry( p->rVars.pRoot, pVar, pNext )
00152 pVar->pNext = pVar->pPrev = NULL;
00153 p->rVars.pRoot = NULL;
00154 p->rVars.nItems = 0;
00155 }
00156
00168 int Msat_OrderCheck( Msat_Order_t * p )
00169 {
00170 Msat_OrderVar_t * pVar, * pNext;
00171 Msat_IntVec_t * vRound;
00172 int * pRound, nRound;
00173 int * pVars, nVars, i, k;
00174 int Counter = 0;
00175
00176
00177 Msat_OrderRingForEachEntry( p->rVars.pRoot, pVar, pNext )
00178 {
00179 assert( !Msat_OrderVarIsAssigned(p, pVar->Num) );
00180
00181
00182 vRound = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( p->pSat->vAdjacents, pVar->Num );
00183 nRound = Msat_IntVecReadSize( vRound );
00184 pRound = Msat_IntVecReadArray( vRound );
00185 for ( i = 0; i < nRound; i++ )
00186 {
00187 if ( !Msat_OrderVarIsUsedInCone(p, pRound[i]) )
00188 continue;
00189 if ( Msat_OrderVarIsAssigned(p, pRound[i]) )
00190 break;
00191 }
00192
00193
00194
00195 if ( i == nRound )
00196 Counter++;
00197 }
00198 if ( Counter > 0 )
00199 printf( "%d(%d) ", Counter, p->rVars.nItems );
00200
00201
00202
00203
00204 nVars = Msat_IntVecReadSize( p->pSat->vConeVars );
00205 pVars = Msat_IntVecReadArray( p->pSat->vConeVars );
00206 for ( i = 0; i < nVars; i++ )
00207 {
00208 assert( Msat_OrderVarIsUsedInCone(p, pVars[i]) );
00209
00210 if ( Msat_OrderVarIsAssigned(p, pVars[i]) ||
00211 Msat_OrderVarIsInBoundary(p, pVars[i]) )
00212 continue;
00213
00214 vRound = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( p->pSat->vAdjacents, pVars[i] );
00215 nRound = Msat_IntVecReadSize( vRound );
00216 pRound = Msat_IntVecReadArray( vRound );
00217 for ( k = 0; k < nRound; k++ )
00218 {
00219 if ( !Msat_OrderVarIsUsedInCone(p, pRound[k]) )
00220 continue;
00221 if ( Msat_OrderVarIsAssigned(p, pRound[k]) )
00222 break;
00223 }
00224
00225
00226
00227 }
00228 return 1;
00229 }
00230
00242 void Msat_OrderFree( Msat_Order_t * p )
00243 {
00244 free( p->pVars );
00245 free( p );
00246 }
00247
00259 int Msat_OrderVarSelect( Msat_Order_t * p )
00260 {
00261 Msat_OrderVar_t * pVar, * pNext, * pVarBest;
00262 double * pdActs = p->pSat->pdActivity;
00263 double dfActBest;
00264
00265
00266 pVarBest = NULL;
00267 dfActBest = -1.0;
00268 Msat_OrderRingForEachEntry( p->rVars.pRoot, pVar, pNext )
00269 {
00270 if ( dfActBest < pdActs[pVar->Num] )
00271 {
00272 dfActBest = pdActs[pVar->Num];
00273 pVarBest = pVar;
00274 }
00275 }
00276
00277
00278
00279
00280
00281
00282
00283 if ( pVarBest )
00284 {
00285 assert( Msat_OrderVarIsUsedInCone(p, pVarBest->Num) );
00286 return pVarBest->Num;
00287 }
00288 return MSAT_ORDER_UNKNOWN;
00289 }
00290
00302 void Msat_OrderVarAssigned( Msat_Order_t * p, int Var )
00303 {
00304 Msat_IntVec_t * vRound;
00305 int i;
00306
00307
00308 assert( Var < p->nVarsAlloc );
00309
00310 if ( Msat_OrderVarIsInBoundary( p, Var ) )
00311 Msat_OrderRingRemove( &p->rVars, &p->pVars[Var] );
00312
00313
00314 vRound = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[Var];
00315 for ( i = 0; i < vRound->nSize; i++ )
00316 {
00317 if ( !Msat_OrderVarIsUsedInCone(p, vRound->pArray[i]) )
00318 continue;
00319 if ( Msat_OrderVarIsAssigned(p, vRound->pArray[i]) )
00320 continue;
00321 if ( Msat_OrderVarIsInBoundary(p, vRound->pArray[i]) )
00322 continue;
00323 Msat_OrderRingAddLast( &p->rVars, &p->pVars[vRound->pArray[i]] );
00324 }
00325
00326
00327 }
00328
00340 void Msat_OrderVarUnassigned( Msat_Order_t * p, int Var )
00341 {
00342 Msat_IntVec_t * vRound, * vRound2;
00343 int i, k;
00344
00345
00346 assert( Var < p->nVarsAlloc );
00347 assert( !Msat_OrderVarIsInBoundary( p, Var ) );
00348
00349
00350
00351
00352 vRound = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[Var];
00353 for ( i = 0; i < vRound->nSize; i++ )
00354 if ( Msat_OrderVarIsAssigned(p, vRound->pArray[i]) )
00355 break;
00356 if ( i != vRound->nSize )
00357 Msat_OrderRingAddLast( &p->rVars, &p->pVars[Var] );
00358
00359
00360 for ( i = 0; i < vRound->nSize; i++ )
00361 if ( Msat_OrderVarIsInBoundary(p, vRound->pArray[i]) )
00362 {
00363 assert( !Msat_OrderVarIsAssigned(p, vRound->pArray[i]) );
00364 vRound2 = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[vRound->pArray[i]];
00365
00366 for ( k = 0; k < vRound2->nSize; k++ )
00367 if ( Msat_OrderVarIsAssigned(p, vRound2->pArray[k]) )
00368 break;
00369 if ( k == vRound2->nSize )
00370 Msat_OrderRingRemove( &p->rVars, &p->pVars[vRound->pArray[i]] );
00371 }
00372
00373
00374 }
00375
00387 void Msat_OrderUpdate( Msat_Order_t * p, int Var )
00388 {
00389 }
00390
00391
00403 void Msat_OrderRingAddLast( Msat_OrderRing_t * pRing, Msat_OrderVar_t * pVar )
00404 {
00405
00406
00407 assert( pVar->pPrev == NULL );
00408 assert( pVar->pNext == NULL );
00409
00410 pRing->nItems++;
00411 if ( pRing->pRoot == NULL )
00412 {
00413 pRing->pRoot = pVar;
00414 pVar->pPrev = pVar;
00415 pVar->pNext = pVar;
00416 return;
00417 }
00418
00419 pVar->pPrev = pRing->pRoot->pPrev;
00420 pVar->pNext = pRing->pRoot;
00421 pVar->pPrev->pNext = pVar;
00422 pVar->pNext->pPrev = pVar;
00423
00424
00425
00426 }
00427
00439 void Msat_OrderRingRemove( Msat_OrderRing_t * pRing, Msat_OrderVar_t * pVar )
00440 {
00441
00442
00443 assert( pVar->pPrev );
00444 assert( pVar->pNext );
00445 pRing->nItems--;
00446 if ( pRing->nItems == 0 )
00447 {
00448 assert( pRing->pRoot == pVar );
00449 pVar->pPrev = NULL;
00450 pVar->pNext = NULL;
00451 pRing->pRoot = NULL;
00452 return;
00453 }
00454
00455 if ( pRing->pRoot == pVar )
00456 pRing->pRoot = pVar->pNext;
00457
00458
00459
00460
00461 pVar->pPrev->pNext = pVar->pNext;
00462 pVar->pNext->pPrev = pVar->pPrev;
00463 pVar->pPrev = NULL;
00464 pVar->pNext = NULL;
00465 }
00466
00467
00471
00472