abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
msatOrderJ.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [msatOrder.c]
4 
5  PackageName [A C version of SAT solver MINISAT, originally developed
6  in C++ by Niklas Een and Niklas Sorensson, Chalmers University of
7  Technology, Sweden: http://www.cs.chalmers.se/~een/Satzoo.]
8 
9  Synopsis [The manager of variable assignment.]
10 
11  Author [Alan Mishchenko <alanmi@eecs.berkeley.edu>]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - January 1, 2004.]
16 
17  Revision [$Id: msatOrder.c,v 1.0 2005/05/30 1:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "msatInt.h"
22 
24 
25 
26 /*
27 The J-boundary (justification boundary) is defined as a set of unassigned
28 variables belonging to the cone of interest, such that for each of them,
29 there exist an adjacent assigned variable in the cone of interest.
30 */
31 
32 ////////////////////////////////////////////////////////////////////////
33 /// DECLARATIONS ///
34 ////////////////////////////////////////////////////////////////////////
35 
38 
39 // the variable data structure
41 {
44  int Num;
45 };
46 
47 // the ring of variables data structure (J-boundary)
49 {
51  int nItems;
52 };
53 
54 // the variable package data structure
55 struct Msat_Order_t_
56 {
57  Msat_Solver_t * pSat; // the SAT solver
58  Msat_OrderVar_t * pVars; // the storage for variables
59  int nVarsAlloc; // the number of variables allocated
60  Msat_OrderRing_t rVars; // the J-boundary as a ring of variables
61 };
62 
63 //The solver can communicate to the variable order the following parts:
64 //- the array of current assignments (pSat->pAssigns)
65 //- the array of variable activities (pSat->pdActivity)
66 //- the array of variables currently in the cone (pSat->vConeVars)
67 //- the array of arrays of variables adjucent to each(pSat->vAdjacents)
68 
69 #define Msat_OrderVarIsInBoundary( p, i ) ((p)->pVars[i].pNext)
70 #define Msat_OrderVarIsAssigned( p, i ) ((p)->pSat->pAssigns[i] != MSAT_VAR_UNASSIGNED)
71 #define Msat_OrderVarIsUsedInCone( p, i ) ((p)->pSat->vVarsUsed->pArray[i])
72 
73 // iterator through the entries in J-boundary
74 #define Msat_OrderRingForEachEntry( pRing, pVar, pNext ) \
75  for ( pVar = pRing, \
76  pNext = pVar? pVar->pNext : NULL; \
77  pVar; \
78  pVar = (pNext != pRing)? pNext : NULL, \
79  pNext = pVar? pVar->pNext : NULL )
80 
81 static void Msat_OrderRingAddLast( Msat_OrderRing_t * pRing, Msat_OrderVar_t * pVar );
82 static void Msat_OrderRingRemove( Msat_OrderRing_t * pRing, Msat_OrderVar_t * pVar );
83 
84 extern clock_t timeSelect;
85 extern clock_t timeAssign;
86 
87 ////////////////////////////////////////////////////////////////////////
88 /// FUNCTION DEFINITIONS ///
89 ////////////////////////////////////////////////////////////////////////
90 
91 /**Function*************************************************************
92 
93  Synopsis [Allocates the ordering structure.]
94 
95  Description []
96 
97  SideEffects []
98 
99  SeeAlso []
100 
101 ***********************************************************************/
103 {
104  Msat_Order_t * p;
105  p = ALLOC( Msat_Order_t, 1 );
106  memset( p, 0, sizeof(Msat_Order_t) );
107  p->pSat = pSat;
108  Msat_OrderSetBounds( p, pSat->nVarsAlloc );
109  return p;
110 }
111 
112 /**Function*************************************************************
113 
114  Synopsis [Sets the bound of the ordering structure.]
115 
116  Description [Should be called whenever the SAT solver is resized.]
117 
118  SideEffects []
119 
120  SeeAlso []
121 
122 ***********************************************************************/
123 void Msat_OrderSetBounds( Msat_Order_t * p, int nVarsMax )
124 {
125  int i;
126  // add variables if they are missing
127  if ( p->nVarsAlloc < nVarsMax )
128  {
129  p->pVars = REALLOC( Msat_OrderVar_t, p->pVars, nVarsMax );
130  for ( i = p->nVarsAlloc; i < nVarsMax; i++ )
131  {
132  p->pVars[i].pNext = p->pVars[i].pPrev = NULL;
133  p->pVars[i].Num = i;
134  }
135  p->nVarsAlloc = nVarsMax;
136  }
137 }
138 
139 /**Function*************************************************************
140 
141  Synopsis [Cleans the ordering structure.]
142 
143  Description []
144 
145  SideEffects []
146 
147  SeeAlso []
148 
149 ***********************************************************************/
151 {
152  Msat_OrderVar_t * pVar, * pNext;
153  // quickly undo the ring
154  Msat_OrderRingForEachEntry( p->rVars.pRoot, pVar, pNext )
155  pVar->pNext = pVar->pPrev = NULL;
156  p->rVars.pRoot = NULL;
157  p->rVars.nItems = 0;
158 }
159 
160 /**Function*************************************************************
161 
162  Synopsis [Checks that the J-boundary is okay.]
163 
164  Description []
165 
166  SideEffects []
167 
168  SeeAlso []
169 
170 ***********************************************************************/
172 {
173  Msat_OrderVar_t * pVar, * pNext;
174  Msat_IntVec_t * vRound;
175  int * pRound, nRound;
176  int * pVars, nVars, i, k;
177  int Counter = 0;
178 
179  // go through all the variables in the boundary
180  Msat_OrderRingForEachEntry( p->rVars.pRoot, pVar, pNext )
181  {
182  assert( !Msat_OrderVarIsAssigned(p, pVar->Num) );
183  // go though all the variables in the neighborhood
184  // and check that it is true that there is least one assigned
185  vRound = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( p->pSat->vAdjacents, pVar->Num );
186  nRound = Msat_IntVecReadSize( vRound );
187  pRound = Msat_IntVecReadArray( vRound );
188  for ( i = 0; i < nRound; i++ )
189  {
190  if ( !Msat_OrderVarIsUsedInCone(p, pRound[i]) )
191  continue;
192  if ( Msat_OrderVarIsAssigned(p, pRound[i]) )
193  break;
194  }
195 // assert( i != nRound );
196 // if ( i == nRound )
197 // return 0;
198  if ( i == nRound )
199  Counter++;
200  }
201  if ( Counter > 0 )
202  printf( "%d(%d) ", Counter, p->rVars.nItems );
203 
204  // we may also check other unassigned variables in the cone
205  // to make sure that if they are not in J-boundary,
206  // then they do not have an assigned neighbor
207  nVars = Msat_IntVecReadSize( p->pSat->vConeVars );
208  pVars = Msat_IntVecReadArray( p->pSat->vConeVars );
209  for ( i = 0; i < nVars; i++ )
210  {
211  assert( Msat_OrderVarIsUsedInCone(p, pVars[i]) );
212  // skip assigned vars, vars in the boundary, and vars not used in the cone
213  if ( Msat_OrderVarIsAssigned(p, pVars[i]) ||
214  Msat_OrderVarIsInBoundary(p, pVars[i]) )
215  continue;
216  // make sure, it does not have assigned neighbors
217  vRound = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( p->pSat->vAdjacents, pVars[i] );
218  nRound = Msat_IntVecReadSize( vRound );
219  pRound = Msat_IntVecReadArray( vRound );
220  for ( k = 0; k < nRound; k++ )
221  {
222  if ( !Msat_OrderVarIsUsedInCone(p, pRound[k]) )
223  continue;
224  if ( Msat_OrderVarIsAssigned(p, pRound[k]) )
225  break;
226  }
227 // assert( k == nRound );
228 // if ( k != nRound )
229 // return 0;
230  }
231  return 1;
232 }
233 
234 /**Function*************************************************************
235 
236  Synopsis [Frees the ordering structure.]
237 
238  Description []
239 
240  SideEffects []
241 
242  SeeAlso []
243 
244 ***********************************************************************/
246 {
247  free( p->pVars );
248  free( p );
249 }
250 
251 /**Function*************************************************************
252 
253  Synopsis [Selects the next variable to assign.]
254 
255  Description []
256 
257  SideEffects []
258 
259  SeeAlso []
260 
261 ***********************************************************************/
263 {
264  Msat_OrderVar_t * pVar, * pNext, * pVarBest;
265  double * pdActs = p->pSat->pdActivity;
266  double dfActBest;
267 // clock_t clk = clock();
268 
269  pVarBest = NULL;
270  dfActBest = -1.0;
271  Msat_OrderRingForEachEntry( p->rVars.pRoot, pVar, pNext )
272  {
273  if ( dfActBest < pdActs[pVar->Num] )
274  {
275  dfActBest = pdActs[pVar->Num];
276  pVarBest = pVar;
277  }
278  }
279 //timeSelect += clock() - clk;
280 //timeAssign += clock() - clk;
281 
282 //if ( pVarBest && pVarBest->Num % 1000 == 0 )
283 //printf( "%d ", p->rVars.nItems );
284 
285 // Msat_OrderCheck( p );
286  if ( pVarBest )
287  {
288  assert( Msat_OrderVarIsUsedInCone(p, pVarBest->Num) );
289  return pVarBest->Num;
290  }
291  return MSAT_ORDER_UNKNOWN;
292 }
293 
294 /**Function*************************************************************
295 
296  Synopsis [Updates J-boundary when the variable is assigned.]
297 
298  Description []
299 
300  SideEffects []
301 
302  SeeAlso []
303 
304 ***********************************************************************/
306 {
307  Msat_IntVec_t * vRound;
308  int i;//, clk = clock();
309 
310  // make sure the variable is in the boundary
311  assert( Var < p->nVarsAlloc );
312  // if it is not in the boundary (initial decision, random decision), do not remove
313  if ( Msat_OrderVarIsInBoundary( p, Var ) )
314  Msat_OrderRingRemove( &p->rVars, &p->pVars[Var] );
315  // add to the boundary those neighbors that are (1) unassigned, (2) not in boundary
316  // because for them we know that there is a variable (Var) which is assigned
317  vRound = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[Var];
318  for ( i = 0; i < vRound->nSize; i++ )
319  {
320  if ( !Msat_OrderVarIsUsedInCone(p, vRound->pArray[i]) )
321  continue;
322  if ( Msat_OrderVarIsAssigned(p, vRound->pArray[i]) )
323  continue;
324  if ( Msat_OrderVarIsInBoundary(p, vRound->pArray[i]) )
325  continue;
326  Msat_OrderRingAddLast( &p->rVars, &p->pVars[vRound->pArray[i]] );
327  }
328 //timeSelect += clock() - clk;
329 // Msat_OrderCheck( p );
330 }
331 
332 /**Function*************************************************************
333 
334  Synopsis [Updates the order after a variable is unassigned.]
335 
336  Description []
337 
338  SideEffects []
339 
340  SeeAlso []
341 
342 ***********************************************************************/
344 {
345  Msat_IntVec_t * vRound, * vRound2;
346  int i, k;//, clk = clock();
347 
348  // make sure the variable is not in the boundary
349  assert( Var < p->nVarsAlloc );
350  assert( !Msat_OrderVarIsInBoundary( p, Var ) );
351  // go through its neigbors - if one of them is assigned add this var
352  // add to the boundary those neighbors that are not there already
353  // this will also get rid of variable outside of the current cone
354  // because they are unassigned in Msat_SolverPrepare()
355  vRound = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[Var];
356  for ( i = 0; i < vRound->nSize; i++ )
357  if ( Msat_OrderVarIsAssigned(p, vRound->pArray[i]) )
358  break;
359  if ( i != vRound->nSize )
360  Msat_OrderRingAddLast( &p->rVars, &p->pVars[Var] );
361 
362  // unassigning a variable may lead to its adjacents dropping from the boundary
363  for ( i = 0; i < vRound->nSize; i++ )
364  if ( Msat_OrderVarIsInBoundary(p, vRound->pArray[i]) )
365  { // the neighbor is in the J-boundary (and unassigned)
366  assert( !Msat_OrderVarIsAssigned(p, vRound->pArray[i]) );
367  vRound2 = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[vRound->pArray[i]];
368  // go through its neighbors and determine if there is at least one assigned
369  for ( k = 0; k < vRound2->nSize; k++ )
370  if ( Msat_OrderVarIsAssigned(p, vRound2->pArray[k]) )
371  break;
372  if ( k == vRound2->nSize ) // there is no assigned vars, delete this one
373  Msat_OrderRingRemove( &p->rVars, &p->pVars[vRound->pArray[i]] );
374  }
375 //timeSelect += clock() - clk;
376 // Msat_OrderCheck( p );
377 }
378 
379 /**Function*************************************************************
380 
381  Synopsis [Updates the order after a variable changed weight.]
382 
383  Description []
384 
385  SideEffects []
386 
387  SeeAlso []
388 
389 ***********************************************************************/
391 {
392 }
393 
394 
395 /**Function*************************************************************
396 
397  Synopsis [Adds node to the end of the ring.]
398 
399  Description []
400 
401  SideEffects []
402 
403  SeeAlso []
404 
405 ***********************************************************************/
407 {
408 //printf( "adding %d\n", pVar->Num );
409  // check that the node is not in a ring
410  assert( pVar->pPrev == NULL );
411  assert( pVar->pNext == NULL );
412  // if the ring is empty, make the node point to itself
413  pRing->nItems++;
414  if ( pRing->pRoot == NULL )
415  {
416  pRing->pRoot = pVar;
417  pVar->pPrev = pVar;
418  pVar->pNext = pVar;
419  return;
420  }
421  // if the ring is not empty, add it as the last entry
422  pVar->pPrev = pRing->pRoot->pPrev;
423  pVar->pNext = pRing->pRoot;
424  pVar->pPrev->pNext = pVar;
425  pVar->pNext->pPrev = pVar;
426 
427  // move the root so that it points to the new entry
428 // pRing->pRoot = pRing->pRoot->pPrev;
429 }
430 
431 /**Function*************************************************************
432 
433  Synopsis [Removes the node from the ring.]
434 
435  Description []
436 
437  SideEffects []
438 
439  SeeAlso []
440 
441 ***********************************************************************/
443 {
444 //printf( "removing %d\n", pVar->Num );
445  // check that the var is in a ring
446  assert( pVar->pPrev );
447  assert( pVar->pNext );
448  pRing->nItems--;
449  if ( pRing->nItems == 0 )
450  {
451  assert( pRing->pRoot == pVar );
452  pVar->pPrev = NULL;
453  pVar->pNext = NULL;
454  pRing->pRoot = NULL;
455  return;
456  }
457  // move the root if needed
458  if ( pRing->pRoot == pVar )
459  pRing->pRoot = pVar->pNext;
460  // move the root to the next entry after pVar
461  // this way all the additions to the list will be traversed first
462 // pRing->pRoot = pVar->pPrev;
463  // delete the node
464  pVar->pPrev->pNext = pVar->pNext;
465  pVar->pNext->pPrev = pVar->pPrev;
466  pVar->pPrev = NULL;
467  pVar->pNext = NULL;
468 }
469 
470 
471 ////////////////////////////////////////////////////////////////////////
472 /// END OF FILE ///
473 ////////////////////////////////////////////////////////////////////////
474 
475 
477 
char * memset()
void Msat_OrderClean(Msat_Order_t *p, Msat_IntVec_t *vCone)
Definition: msatOrderJ.c:150
Msat_Order_t * Msat_OrderAlloc(Msat_Solver_t *pSat)
FUNCTION DEFINITIONS ///.
Definition: msatOrderJ.c:102
VOID_HACK free()
#define MSAT_ORDER_UNKNOWN
Definition: msatInt.h:70
static Llb_Mgr_t * p
Definition: llb3Image.c:950
Msat_Clause_t * Msat_ClauseVecReadEntry(Msat_ClauseVec_t *p, int i)
DECLARATIONS ///.
Definition: msatOrderH.c:31
static void Msat_OrderRingAddLast(Msat_OrderRing_t *pRing, Msat_OrderVar_t *pVar)
Definition: msatOrderJ.c:406
Msat_OrderRing_t rVars
Definition: msatOrderJ.c:60
clock_t timeAssign
Definition: fraigMan.c:29
clock_t timeSelect
DECLARATIONS ///.
Definition: fraigMan.c:28
void Msat_OrderSetBounds(Msat_Order_t *p, int nVarsMax)
Definition: msatOrderJ.c:123
for(p=first;p->value< newval;p=p->next)
void Msat_OrderUpdate(Msat_Order_t *p, int Var)
Definition: msatOrderJ.c:390
int Msat_OrderCheck(Msat_Order_t *p)
Definition: msatOrderJ.c:171
Msat_OrderVar_t * pPrev
Definition: msatOrderJ.c:43
int Msat_IntVecReadSize(Msat_IntVec_t *p)
Definition: msatVec.c:233
#define ALLOC(type, num)
Definition: avl.h:27
void Msat_OrderVarUnassigned(Msat_Order_t *p, int Var)
Definition: msatOrderJ.c:343
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
typedefABC_NAMESPACE_IMPL_START struct Msat_OrderVar_t_ Msat_OrderVar_t
DECLARATIONS ///.
Definition: msatOrderJ.c:36
static int Counter
void Msat_OrderFree(Msat_Order_t *p)
Definition: msatOrderJ.c:245
void Msat_OrderVarAssigned(Msat_Order_t *p, int Var)
Definition: msatOrderJ.c:305
#define REALLOC(type, obj, num)
Definition: avl.h:29
#define Msat_OrderVarIsInBoundary(p, i)
Definition: msatOrderJ.c:69
static void Msat_OrderRingRemove(Msat_OrderRing_t *pRing, Msat_OrderVar_t *pVar)
Definition: msatOrderJ.c:442
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
#define Msat_OrderVarIsAssigned(p, i)
Definition: msatOrderJ.c:70
int Msat_OrderVarSelect(Msat_Order_t *p)
Definition: msatOrderJ.c:262
int * Msat_IntVecReadArray(Msat_IntVec_t *p)
Definition: msatVec.c:217
Msat_OrderVar_t * pNext
Definition: msatOrderJ.c:42
int Var
Definition: SolverTypes.h:42
#define Msat_OrderRingForEachEntry(pRing, pVar, pNext)
Definition: msatOrderJ.c:74
#define assert(ex)
Definition: util_old.h:213
Msat_OrderVar_t * pRoot
Definition: msatOrderJ.c:50
#define Msat_OrderVarIsUsedInCone(p, i)
Definition: msatOrderJ.c:71
int * pArray
Definition: msatInt.h:164
typedefABC_NAMESPACE_HEADER_START struct Msat_Solver_t_ Msat_Solver_t
INCLUDES ///.
Definition: msat.h:42
Msat_OrderVar_t * pVars
Definition: msatOrderJ.c:58
Msat_Solver_t * pSat
Definition: msatOrderH.c:33