abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
satInterP.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [satInter.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [SAT sat_solver.]
8 
9  Synopsis [Interpolation package.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - June 20, 2005.]
16 
17  Revision [$Id: satInter.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
18 
19 ***********************************************************************/
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <assert.h>
25 
26 #include "satStore.h"
27 #include "misc/vec/vec.h"
28 
30 
31 
32 ////////////////////////////////////////////////////////////////////////
33 /// DECLARATIONS ///
34 ////////////////////////////////////////////////////////////////////////
35 
36 // variable assignments
37 static const lit LIT_UNDEF = 0xffffffff;
38 
39 // interpolation manager
41 {
42  // clauses of the problems
43  Sto_Man_t * pCnf; // the set of CNF clauses for A and B
44  // various parameters
45  int fVerbose; // verbosiness flag
46  int fProofVerif; // verifies the proof
47  int fProofWrite; // writes the proof file
48  int nVarsAlloc; // the allocated size of var arrays
49  int nClosAlloc; // the allocated size of clause arrays
50  // internal BCP
51  int nRootSize; // the number of root level assignments
52  int nTrailSize; // the number of assignments made
53  lit * pTrail; // chronological order of assignments (size nVars)
54  lit * pAssigns; // assignments by variable (size nVars)
55  char * pSeens; // temporary mark (size nVars)
56  Sto_Cls_t ** pReasons; // reasons for each assignment (size nVars)
57  Sto_Cls_t ** pWatches; // watched clauses for each literal (size 2*nVars)
58  // proof data
59 // Vec_Int_t * vAnties; // anticedents for all clauses
60 // Vec_Int_t * vBreaks; // beginnings of anticedents for each clause
61  Vec_Ptr_t * vAntClas; // anticedant clauses
62  int nAntStart; // starting antecedant clause
63  // proof recording
64  int Counter; // counter of resolved clauses
65  int * pProofNums; // the proof numbers for each clause (size nClauses)
66  FILE * pFile; // the file for proof recording
67  // internal verification
68  lit * pResLits; // the literals of the resolvent
69  int nResLits; // the number of literals of the resolvent
70  int nResLitsAlloc;// the number of literals of the resolvent
71  // runtime stats
72  abctime timeBcp; // the runtime for BCP
73  abctime timeTrace; // the runtime of trace construction
74  abctime timeTotal; // the total runtime of interpolation
75 };
76 
77 // reading/writing the proof for a clause
78 static inline int Intp_ManProofGet( Intp_Man_t * p, Sto_Cls_t * pCls ) { return p->pProofNums[pCls->Id]; }
79 static inline void Intp_ManProofSet( Intp_Man_t * p, Sto_Cls_t * pCls, int n ) { p->pProofNums[pCls->Id] = n; }
80 
81 ////////////////////////////////////////////////////////////////////////
82 /// FUNCTION DEFINITIONS ///
83 ////////////////////////////////////////////////////////////////////////
84 
85 /**Function*************************************************************
86 
87  Synopsis [Allocate proof manager.]
88 
89  Description []
90 
91  SideEffects []
92 
93  SeeAlso []
94 
95 ***********************************************************************/
97 {
98  Intp_Man_t * p;
99  // allocate the manager
100  p = (Intp_Man_t *)ABC_ALLOC( char, sizeof(Intp_Man_t) );
101  memset( p, 0, sizeof(Intp_Man_t) );
102  // verification
103  p->nResLitsAlloc = (1<<16);
104  p->pResLits = ABC_ALLOC( lit, p->nResLitsAlloc );
105  // proof recording
106 // p->vAnties = Vec_IntAlloc( 1000 );
107 // p->vBreaks = Vec_IntAlloc( 1000 );
108  p->vAntClas = Vec_PtrAlloc( 1000 );
109  p->nAntStart = 0;
110  // parameters
111  p->fProofWrite = 0;
112  p->fProofVerif = 1;
113  return p;
114 }
115 
116 /**Function*************************************************************
117 
118  Synopsis [Resize proof manager.]
119 
120  Description []
121 
122  SideEffects []
123 
124  SeeAlso []
125 
126 ***********************************************************************/
128 {
129  // check if resizing is needed
130  if ( p->nVarsAlloc < p->pCnf->nVars )
131  {
132  // find the new size
133  if ( p->nVarsAlloc == 0 )
134  p->nVarsAlloc = 1;
135  while ( p->nVarsAlloc < p->pCnf->nVars )
136  p->nVarsAlloc *= 2;
137  // resize the arrays
138  p->pTrail = ABC_REALLOC(lit, p->pTrail, p->nVarsAlloc );
139  p->pAssigns = ABC_REALLOC(lit, p->pAssigns, p->nVarsAlloc );
140  p->pSeens = ABC_REALLOC(char, p->pSeens, p->nVarsAlloc );
141 // p->pVarTypes = ABC_REALLOC(int, p->pVarTypes, p->nVarsAlloc );
143  p->pWatches = ABC_REALLOC(Sto_Cls_t *, p->pWatches, p->nVarsAlloc*2 );
144  }
145 
146  // clean the free space
147  memset( p->pAssigns , 0xff, sizeof(lit) * p->pCnf->nVars );
148  memset( p->pSeens , 0, sizeof(char) * p->pCnf->nVars );
149 // memset( p->pVarTypes, 0, sizeof(int) * p->pCnf->nVars );
150  memset( p->pReasons , 0, sizeof(Sto_Cls_t *) * p->pCnf->nVars );
151  memset( p->pWatches , 0, sizeof(Sto_Cls_t *) * p->pCnf->nVars*2 );
152 
153  // check if resizing of clauses is needed
154  if ( p->nClosAlloc < p->pCnf->nClauses )
155  {
156  // find the new size
157  if ( p->nClosAlloc == 0 )
158  p->nClosAlloc = 1;
159  while ( p->nClosAlloc < p->pCnf->nClauses )
160  p->nClosAlloc *= 2;
161  // resize the arrays
162  p->pProofNums = ABC_REALLOC( int, p->pProofNums, p->nClosAlloc );
163  }
164  memset( p->pProofNums, 0, sizeof(int) * p->pCnf->nClauses );
165 }
166 
167 /**Function*************************************************************
168 
169  Synopsis [Deallocate proof manager.]
170 
171  Description []
172 
173  SideEffects []
174 
175  SeeAlso []
176 
177 ***********************************************************************/
179 {
180 /*
181  printf( "Runtime stats:\n" );
182 ABC_PRT( "BCP ", p->timeBcp );
183 ABC_PRT( "Trace ", p->timeTrace );
184 ABC_PRT( "TOTAL ", p->timeTotal );
185 */
186 // Vec_IntFree( p->vAnties );
187 // Vec_IntFree( p->vBreaks );
188  Vec_VecFree( (Vec_Vec_t *)p->vAntClas );
189 // ABC_FREE( p->pInters );
190  ABC_FREE( p->pProofNums );
191  ABC_FREE( p->pTrail );
192  ABC_FREE( p->pAssigns );
193  ABC_FREE( p->pSeens );
194 // ABC_FREE( p->pVarTypes );
195  ABC_FREE( p->pReasons );
196  ABC_FREE( p->pWatches );
197  ABC_FREE( p->pResLits );
198  ABC_FREE( p );
199 }
200 
201 
202 
203 
204 /**Function*************************************************************
205 
206  Synopsis [Prints the clause.]
207 
208  Description []
209 
210  SideEffects []
211 
212  SeeAlso []
213 
214 ***********************************************************************/
216 {
217  int i;
218  printf( "Clause ID = %d. Proof = %d. {", pClause->Id, Intp_ManProofGet(p, pClause) );
219  for ( i = 0; i < (int)pClause->nLits; i++ )
220  printf( " %d", pClause->pLits[i] );
221  printf( " }\n" );
222 }
223 
224 /**Function*************************************************************
225 
226  Synopsis [Prints the resolvent.]
227 
228  Description []
229 
230  SideEffects []
231 
232  SeeAlso []
233 
234 ***********************************************************************/
235 void Intp_ManPrintResolvent( lit * pResLits, int nResLits )
236 {
237  int i;
238  printf( "Resolvent: {" );
239  for ( i = 0; i < nResLits; i++ )
240  printf( " %d", pResLits[i] );
241  printf( " }\n" );
242 }
243 
244 /**Function*************************************************************
245 
246  Synopsis [Prints the interpolant for one clause.]
247 
248  Description []
249 
250  SideEffects []
251 
252  SeeAlso []
253 
254 ***********************************************************************/
256 {
257  printf( "Clause %2d : ", pClause->Id );
258 // Extra_PrintBinary___( stdout, Intp_ManAigRead(p, pClause), (1 << p->nVarsAB) );
259  printf( "\n" );
260 }
261 
262 
263 
264 /**Function*************************************************************
265 
266  Synopsis [Adds one clause to the watcher list.]
267 
268  Description []
269 
270  SideEffects []
271 
272  SeeAlso []
273 
274 ***********************************************************************/
275 static inline void Intp_ManWatchClause( Intp_Man_t * p, Sto_Cls_t * pClause, lit Lit )
276 {
277  assert( lit_check(Lit, p->pCnf->nVars) );
278  if ( pClause->pLits[0] == Lit )
279  pClause->pNext0 = p->pWatches[lit_neg(Lit)];
280  else
281  {
282  assert( pClause->pLits[1] == Lit );
283  pClause->pNext1 = p->pWatches[lit_neg(Lit)];
284  }
285  p->pWatches[lit_neg(Lit)] = pClause;
286 }
287 
288 
289 /**Function*************************************************************
290 
291  Synopsis [Records implication.]
292 
293  Description []
294 
295  SideEffects []
296 
297  SeeAlso []
298 
299 ***********************************************************************/
300 static inline int Intp_ManEnqueue( Intp_Man_t * p, lit Lit, Sto_Cls_t * pReason )
301 {
302  int Var = lit_var(Lit);
303  if ( p->pAssigns[Var] != LIT_UNDEF )
304  return p->pAssigns[Var] == Lit;
305  p->pAssigns[Var] = Lit;
306  p->pReasons[Var] = pReason;
307  p->pTrail[p->nTrailSize++] = Lit;
308 //printf( "assigning var %d value %d\n", Var, !lit_sign(Lit) );
309  return 1;
310 }
311 
312 /**Function*************************************************************
313 
314  Synopsis [Records implication.]
315 
316  Description []
317 
318  SideEffects []
319 
320  SeeAlso []
321 
322 ***********************************************************************/
323 static inline void Intp_ManCancelUntil( Intp_Man_t * p, int Level )
324 {
325  lit Lit;
326  int i, Var;
327  for ( i = p->nTrailSize - 1; i >= Level; i-- )
328  {
329  Lit = p->pTrail[i];
330  Var = lit_var( Lit );
331  p->pReasons[Var] = NULL;
332  p->pAssigns[Var] = LIT_UNDEF;
333 //printf( "cancelling var %d\n", Var );
334  }
335  p->nTrailSize = Level;
336 }
337 
338 /**Function*************************************************************
339 
340  Synopsis [Propagate one assignment.]
341 
342  Description []
343 
344  SideEffects []
345 
346  SeeAlso []
347 
348 ***********************************************************************/
349 static inline Sto_Cls_t * Intp_ManPropagateOne( Intp_Man_t * p, lit Lit )
350 {
351  Sto_Cls_t ** ppPrev, * pCur, * pTemp;
352  lit LitF = lit_neg(Lit);
353  int i;
354  // iterate through the literals
355  ppPrev = p->pWatches + Lit;
356  for ( pCur = p->pWatches[Lit]; pCur; pCur = *ppPrev )
357  {
358  // make sure the false literal is in the second literal of the clause
359  if ( pCur->pLits[0] == LitF )
360  {
361  pCur->pLits[0] = pCur->pLits[1];
362  pCur->pLits[1] = LitF;
363  pTemp = pCur->pNext0;
364  pCur->pNext0 = pCur->pNext1;
365  pCur->pNext1 = pTemp;
366  }
367  assert( pCur->pLits[1] == LitF );
368 
369  // if the first literal is true, the clause is satisfied
370  if ( pCur->pLits[0] == p->pAssigns[lit_var(pCur->pLits[0])] )
371  {
372  ppPrev = &pCur->pNext1;
373  continue;
374  }
375 
376  // look for a new literal to watch
377  for ( i = 2; i < (int)pCur->nLits; i++ )
378  {
379  // skip the case when the literal is false
380  if ( lit_neg(pCur->pLits[i]) == p->pAssigns[lit_var(pCur->pLits[i])] )
381  continue;
382  // the literal is either true or unassigned - watch it
383  pCur->pLits[1] = pCur->pLits[i];
384  pCur->pLits[i] = LitF;
385  // remove this clause from the watch list of Lit
386  *ppPrev = pCur->pNext1;
387  // add this clause to the watch list of pCur->pLits[i] (now it is pCur->pLits[1])
388  Intp_ManWatchClause( p, pCur, pCur->pLits[1] );
389  break;
390  }
391  if ( i < (int)pCur->nLits ) // found new watch
392  continue;
393 
394  // clause is unit - enqueue new implication
395  if ( Intp_ManEnqueue(p, pCur->pLits[0], pCur) )
396  {
397  ppPrev = &pCur->pNext1;
398  continue;
399  }
400 
401  // conflict detected - return the conflict clause
402  return pCur;
403  }
404  return NULL;
405 }
406 
407 /**Function*************************************************************
408 
409  Synopsis [Propagate the current assignments.]
410 
411  Description []
412 
413  SideEffects []
414 
415  SeeAlso []
416 
417 ***********************************************************************/
419 {
420  Sto_Cls_t * pClause;
421  int i;
422  abctime clk = Abc_Clock();
423  for ( i = Start; i < p->nTrailSize; i++ )
424  {
425  pClause = Intp_ManPropagateOne( p, p->pTrail[i] );
426  if ( pClause )
427  {
428 p->timeBcp += Abc_Clock() - clk;
429  return pClause;
430  }
431  }
432 p->timeBcp += Abc_Clock() - clk;
433  return NULL;
434 }
435 
436 
437 /**Function*************************************************************
438 
439  Synopsis [Writes one root clause into a file.]
440 
441  Description []
442 
443  SideEffects []
444 
445  SeeAlso []
446 
447 ***********************************************************************/
449 {
450  Intp_ManProofSet( p, pClause, ++p->Counter );
451 
452  if ( p->fProofWrite )
453  {
454  int v;
455  fprintf( p->pFile, "%d", Intp_ManProofGet(p, pClause) );
456  for ( v = 0; v < (int)pClause->nLits; v++ )
457  fprintf( p->pFile, " %d", lit_print(pClause->pLits[v]) );
458  fprintf( p->pFile, " 0 0\n" );
459  }
460 }
461 
462 /**Function*************************************************************
463 
464  Synopsis [Traces the proof for one clause.]
465 
466  Description []
467 
468  SideEffects []
469 
470  SeeAlso []
471 
472 ***********************************************************************/
473 int Intp_ManProofTraceOne( Intp_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pFinal )
474 {
475  Sto_Cls_t * pReason;
476  int i, v, Var, PrevId;
477  int fPrint = 0;
478  abctime clk = Abc_Clock();
479 
480  // collect resolvent literals
481  if ( p->fProofVerif )
482  {
483  assert( (int)pConflict->nLits <= p->nResLitsAlloc );
484  memcpy( p->pResLits, pConflict->pLits, sizeof(lit) * pConflict->nLits );
485  p->nResLits = pConflict->nLits;
486  }
487 
488  // mark all the variables in the conflict as seen
489  for ( v = 0; v < (int)pConflict->nLits; v++ )
490  p->pSeens[lit_var(pConflict->pLits[v])] = 1;
491 
492  // start the anticedents
493 // pFinal->pAntis = Vec_PtrAlloc( 32 );
494 // Vec_PtrPush( pFinal->pAntis, pConflict );
495 
496 // assert( pFinal->Id == Vec_IntSize(p->vBreaks) );
497 // Vec_IntPush( p->vBreaks, Vec_IntSize(p->vAnties) );
498 // Vec_IntPush( p->vAnties, pConflict->Id );
499  {
500  Vec_Int_t * vAnts = Vec_IntAlloc( 16 );
501  assert( Vec_PtrSize(p->vAntClas) == pFinal->Id - p->nAntStart );
502  Vec_IntPush( vAnts, pConflict->Id );
503  Vec_PtrPush( p->vAntClas, vAnts );
504  }
505 
506 // if ( p->pCnf->nClausesA )
507 // Intp_ManAigCopy( p, Intp_ManAigRead(p, pFinal), Intp_ManAigRead(p, pConflict) );
508 
509  // follow the trail backwards
510  PrevId = Intp_ManProofGet(p, pConflict);
511  for ( i = p->nTrailSize - 1; i >= 0; i-- )
512  {
513  // skip literals that are not involved
514  Var = lit_var(p->pTrail[i]);
515  if ( !p->pSeens[Var] )
516  continue;
517  p->pSeens[Var] = 0;
518 
519  // skip literals of the resulting clause
520  pReason = p->pReasons[Var];
521  if ( pReason == NULL )
522  continue;
523  assert( p->pTrail[i] == pReason->pLits[0] );
524 
525  // add the variables to seen
526  for ( v = 1; v < (int)pReason->nLits; v++ )
527  p->pSeens[lit_var(pReason->pLits[v])] = 1;
528 
529 
530  // record the reason clause
531  assert( Intp_ManProofGet(p, pReason) > 0 );
532  p->Counter++;
533  if ( p->fProofWrite )
534  fprintf( p->pFile, "%d * %d %d 0\n", p->Counter, PrevId, Intp_ManProofGet(p, pReason) );
535  PrevId = p->Counter;
536 
537 // if ( p->pCnf->nClausesA )
538 // {
539 // if ( p->pVarTypes[Var] == 1 ) // var of A
540 // Intp_ManAigOr( p, Intp_ManAigRead(p, pFinal), Intp_ManAigRead(p, pReason) );
541 // else
542 // Intp_ManAigAnd( p, Intp_ManAigRead(p, pFinal), Intp_ManAigRead(p, pReason) );
543 // }
544 
545  // resolve the temporary resolvent with the reason clause
546  if ( p->fProofVerif )
547  {
548  int v1, v2;
549  if ( fPrint )
551  // check that the var is present in the resolvent
552  for ( v1 = 0; v1 < p->nResLits; v1++ )
553  if ( lit_var(p->pResLits[v1]) == Var )
554  break;
555  if ( v1 == p->nResLits )
556  printf( "Recording clause %d: Cannot find variable %d in the temporary resolvent.\n", pFinal->Id, Var );
557  if ( p->pResLits[v1] != lit_neg(pReason->pLits[0]) )
558  printf( "Recording clause %d: The resolved variable %d is in the wrong polarity.\n", pFinal->Id, Var );
559  // remove this variable from the resolvent
560  assert( lit_var(p->pResLits[v1]) == Var );
561  p->nResLits--;
562  for ( ; v1 < p->nResLits; v1++ )
563  p->pResLits[v1] = p->pResLits[v1+1];
564  // add variables of the reason clause
565  for ( v2 = 1; v2 < (int)pReason->nLits; v2++ )
566  {
567  for ( v1 = 0; v1 < p->nResLits; v1++ )
568  if ( lit_var(p->pResLits[v1]) == lit_var(pReason->pLits[v2]) )
569  break;
570  // if it is a new variable, add it to the resolvent
571  if ( v1 == p->nResLits )
572  {
573  if ( p->nResLits == p->nResLitsAlloc )
574  printf( "Recording clause %d: Ran out of space for intermediate resolvent.\n", pFinal->Id );
575  p->pResLits[ p->nResLits++ ] = pReason->pLits[v2];
576  continue;
577  }
578  // if the variable is the same, the literal should be the same too
579  if ( p->pResLits[v1] == pReason->pLits[v2] )
580  continue;
581  // the literal is different
582  printf( "Recording clause %d: Trying to resolve the clause with more than one opposite literal.\n", pFinal->Id );
583  }
584  }
585 
586 // Vec_PtrPush( pFinal->pAntis, pReason );
587 // Vec_IntPush( p->vAnties, pReason->Id );
588  Vec_IntPush( (Vec_Int_t *)Vec_PtrEntryLast(p->vAntClas), pReason->Id );
589  }
590 
591  // unmark all seen variables
592 // for ( i = p->nTrailSize - 1; i >= 0; i-- )
593 // p->pSeens[lit_var(p->pTrail[i])] = 0;
594  // check that the literals are unmarked
595 // for ( i = p->nTrailSize - 1; i >= 0; i-- )
596 // assert( p->pSeens[lit_var(p->pTrail[i])] == 0 );
597 
598  // use the resulting clause to check the correctness of resolution
599  if ( p->fProofVerif )
600  {
601  int v1, v2;
602  if ( fPrint )
604  for ( v1 = 0; v1 < p->nResLits; v1++ )
605  {
606  for ( v2 = 0; v2 < (int)pFinal->nLits; v2++ )
607  if ( pFinal->pLits[v2] == p->pResLits[v1] )
608  break;
609  if ( v2 < (int)pFinal->nLits )
610  continue;
611  break;
612  }
613  if ( v1 < p->nResLits )
614  {
615  printf( "Recording clause %d: The final resolvent is wrong.\n", pFinal->Id );
616  Intp_ManPrintClause( p, pConflict );
618  Intp_ManPrintClause( p, pFinal );
619  }
620 
621  // if there are literals in the clause that are not in the resolvent
622  // it means that the derived resolvent is stronger than the clause
623  // we can replace the clause with the resolvent by removing these literals
624  if ( p->nResLits != (int)pFinal->nLits )
625  {
626  for ( v1 = 0; v1 < (int)pFinal->nLits; v1++ )
627  {
628  for ( v2 = 0; v2 < p->nResLits; v2++ )
629  if ( pFinal->pLits[v1] == p->pResLits[v2] )
630  break;
631  if ( v2 < p->nResLits )
632  continue;
633  // remove literal v1 from the final clause
634  pFinal->nLits--;
635  for ( v2 = v1; v2 < (int)pFinal->nLits; v2++ )
636  pFinal->pLits[v2] = pFinal->pLits[v2+1];
637  v1--;
638  }
639  assert( p->nResLits == (int)pFinal->nLits );
640  }
641  }
642 p->timeTrace += Abc_Clock() - clk;
643 
644  // return the proof pointer
645 // if ( p->pCnf->nClausesA )
646 // {
647 // Intp_ManPrintInterOne( p, pFinal );
648 // }
649  Intp_ManProofSet( p, pFinal, p->Counter );
650  // make sure the same proof ID is not asssigned to two consecutive clauses
651  assert( p->pProofNums[pFinal->Id-1] != p->Counter );
652 // if ( p->pProofNums[pFinal->Id] == p->pProofNums[pFinal->Id-1] )
653 // p->pProofNums[pFinal->Id] = p->pProofNums[pConflict->Id];
654  return p->Counter;
655 }
656 
657 /**Function*************************************************************
658 
659  Synopsis [Records the proof for one clause.]
660 
661  Description []
662 
663  SideEffects []
664 
665  SeeAlso []
666 
667 ***********************************************************************/
669 {
670  Sto_Cls_t * pConflict;
671  int i;
672 
673  // empty clause never ends up there
674  assert( pClause->nLits > 0 );
675  if ( pClause->nLits == 0 )
676  printf( "Error: Empty clause is attempted.\n" );
677 
678  assert( !pClause->fRoot );
679  assert( p->nTrailSize == p->nRootSize );
680 
681  // if any of the clause literals are already assumed
682  // it means that the clause is redundant and can be skipped
683  for ( i = 0; i < (int)pClause->nLits; i++ )
684  if ( p->pAssigns[lit_var(pClause->pLits[i])] == pClause->pLits[i] )
685  {
686 // Vec_IntPush( p->vBreaks, Vec_IntSize(p->vAnties) );
688  return 1;
689  }
690 
691  // add assumptions to the trail
692  for ( i = 0; i < (int)pClause->nLits; i++ )
693  if ( !Intp_ManEnqueue( p, lit_neg(pClause->pLits[i]), NULL ) )
694  {
695  assert( 0 ); // impossible
696  return 0;
697  }
698 
699  // propagate the assumptions
700  pConflict = Intp_ManPropagate( p, p->nRootSize );
701  if ( pConflict == NULL )
702  {
703  assert( 0 ); // cannot prove
704  return 0;
705  }
706 
707  // skip the clause if it is weaker or the same as the conflict clause
708  if ( pClause->nLits >= pConflict->nLits )
709  {
710  // check if every literal of conflict clause can be found in the given clause
711  int j;
712  for ( i = 0; i < (int)pConflict->nLits; i++ )
713  {
714  for ( j = 0; j < (int)pClause->nLits; j++ )
715  if ( pConflict->pLits[i] == pClause->pLits[j] )
716  break;
717  if ( j == (int)pClause->nLits ) // literal pConflict->pLits[i] is not found
718  break;
719  }
720  if ( i == (int)pConflict->nLits ) // all lits are found
721  {
722  // undo to the root level
724 // Vec_IntPush( p->vBreaks, Vec_IntSize(p->vAnties) );
726  return 1;
727  }
728  }
729 
730  // construct the proof
731  Intp_ManProofTraceOne( p, pConflict, pClause );
732 
733  // undo to the root level
735 
736  // add large clauses to the watched lists
737  if ( pClause->nLits > 1 )
738  {
739  Intp_ManWatchClause( p, pClause, pClause->pLits[0] );
740  Intp_ManWatchClause( p, pClause, pClause->pLits[1] );
741  return 1;
742  }
743  assert( pClause->nLits == 1 );
744 
745  // if the clause proved is unit, add it and propagate
746  if ( !Intp_ManEnqueue( p, pClause->pLits[0], pClause ) )
747  {
748  assert( 0 ); // impossible
749  return 0;
750  }
751 
752  // propagate the assumption
753  pConflict = Intp_ManPropagate( p, p->nRootSize );
754  if ( pConflict )
755  {
756  // insert place-holders till the empty clause
757  while ( Vec_PtrSize(p->vAntClas) < p->pCnf->pEmpty->Id - p->nAntStart )
759  // construct the proof for the empty clause
760  Intp_ManProofTraceOne( p, pConflict, p->pCnf->pEmpty );
761 // if ( p->fVerbose )
762 // printf( "Found last conflict after adding unit clause number %d!\n", pClause->Id );
763  return 0;
764  }
765 
766  // update the root level
767  p->nRootSize = p->nTrailSize;
768  return 1;
769 }
770 
771 /**Function*************************************************************
772 
773  Synopsis [Propagate the root clauses.]
774 
775  Description []
776 
777  SideEffects []
778 
779  SeeAlso []
780 
781 ***********************************************************************/
783 {
784  Sto_Cls_t * pClause;
785  int Counter;
786 
787  // make sure the root clauses are preceeding the learnt clauses
788  Counter = 0;
789  Sto_ManForEachClause( p->pCnf, pClause )
790  {
791  assert( (int)pClause->fA == (Counter < (int)p->pCnf->nClausesA) );
792  assert( (int)pClause->fRoot == (Counter < (int)p->pCnf->nRoots) );
793  Counter++;
794  }
795  assert( p->pCnf->nClauses == Counter );
796 
797  // make sure the last clause if empty
798  assert( p->pCnf->pTail->nLits == 0 );
799 
800  // go through the root unit clauses
801  p->nTrailSize = 0;
802  Sto_ManForEachClauseRoot( p->pCnf, pClause )
803  {
804  // create watcher lists for the root clauses
805  if ( pClause->nLits > 1 )
806  {
807  Intp_ManWatchClause( p, pClause, pClause->pLits[0] );
808  Intp_ManWatchClause( p, pClause, pClause->pLits[1] );
809  }
810  // empty clause and large clauses
811  if ( pClause->nLits != 1 )
812  continue;
813  // unit clause
814  assert( lit_check(pClause->pLits[0], p->pCnf->nVars) );
815  if ( !Intp_ManEnqueue( p, pClause->pLits[0], pClause ) )
816  {
817  // detected root level conflict
818 // printf( "Error in Intp_ManProcessRoots(): Detected a root-level conflict too early!\n" );
819 // assert( 0 );
820  // detected root level conflict
821  Intp_ManProofTraceOne( p, pClause, p->pCnf->pEmpty );
822  if ( p->fVerbose )
823  printf( "Found root level conflict!\n" );
824  return 0;
825  }
826  }
827 
828  // propagate the root unit clauses
829  pClause = Intp_ManPropagate( p, 0 );
830  if ( pClause )
831  {
832  // detected root level conflict
833  Intp_ManProofTraceOne( p, pClause, p->pCnf->pEmpty );
834  if ( p->fVerbose )
835  printf( "Found root level conflict!\n" );
836  return 0;
837  }
838 
839  // set the root level
840  p->nRootSize = p->nTrailSize;
841  return 1;
842 }
843 
844 
845 /**Function*************************************************************
846 
847  Synopsis [Verifies the UNSAT core.]
848 
849  Description [Takes the interpolation manager, the CNF derived by the SAT
850  solver, which includes the root clauses and the learned clauses. Returns
851  the array of integers representing the number of root clauses that are in
852  the UNSAT core.]
853 
854  SideEffects []
855 
856  SeeAlso []
857 
858 ***********************************************************************/
860 {
861  int fVerbose = 0;
862  int nConfMax = 1000000;
863  sat_solver * pSat;
864  Sto_Cls_t * pClause;
865  Vec_Ptr_t * vClauses;
866  int i, iClause, RetValue;
867  abctime clk = Abc_Clock();
868  // collect the clauses
869  vClauses = Vec_PtrAlloc( 1000 );
870  Sto_ManForEachClauseRoot( pCnf, pClause )
871  {
872  assert( Vec_PtrSize(vClauses) == pClause->Id );
873  Vec_PtrPush( vClauses, pClause );
874  }
875  // create new SAT solver
876  pSat = sat_solver_new();
877 // sat_solver_setnvars( pSat, nSatVars );
878  Vec_IntForEachEntry( vCore, iClause, i )
879  {
880  pClause = (Sto_Cls_t *)Vec_PtrEntry( vClauses, iClause );
881  if ( !sat_solver_addclause( pSat, pClause->pLits, pClause->pLits+pClause->nLits ) )
882  {
883  printf( "The core verification problem is trivially UNSAT.\n" );
884  break;
885  }
886  }
887  Vec_PtrFree( vClauses );
888  // solve the problem
889  RetValue = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfMax, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
890  sat_solver_delete( pSat );
891  if ( fVerbose )
892  {
893  if ( RetValue == l_Undef )
894  printf( "Conflict limit is reached. " );
895  else if ( RetValue == l_True )
896  printf( "UNSAT core verification FAILED. " );
897  else
898  printf( "UNSAT core verification succeeded. " );
899  ABC_PRT( "Time", Abc_Clock() - clk );
900  }
901  else
902  {
903  if ( RetValue == l_True )
904  printf( "UNSAT core verification FAILED. \n" );
905  }
906 }
907 
908 /**Function*************************************************************
909 
910  Synopsis [Recursively computes the UNSAT core.]
911 
912  Description []
913 
914  SideEffects []
915 
916  SeeAlso []
917 
918 ***********************************************************************/
919 void Intp_ManUnsatCore_rec( Vec_Ptr_t * vAntClas, int iThis, Vec_Int_t * vCore, int nRoots, Vec_Str_t * vVisited, int fLearned )
920 {
921 // int i, iStop, iStart;
922  Vec_Int_t * vAnt;
923  int i, Entry;
924  // skip visited clauses
925  if ( Vec_StrEntry( vVisited, iThis ) )
926  return;
927  Vec_StrWriteEntry( vVisited, iThis, 1 );
928  // add a root clause to the core
929  if ( iThis < nRoots )
930  {
931  if ( !fLearned )
932  Vec_IntPush( vCore, iThis );
933  return;
934  }
935  // iterate through the clauses
936 // iStart = Vec_IntEntry( vBreaks, iThis );
937 // iStop = Vec_IntEntry( vBreaks, iThis+1 );
938 // assert( iStop != -1 );
939 // for ( i = iStart; i < iStop; i++ )
940  vAnt = (Vec_Int_t *)Vec_PtrEntry( vAntClas, iThis - nRoots );
941  Vec_IntForEachEntry( vAnt, Entry, i )
942 // Intp_ManUnsatCore_rec( vAntClas, Vec_IntEntry(vAnties, i), vCore, nRoots, vVisited );
943  Intp_ManUnsatCore_rec( vAntClas, Entry, vCore, nRoots, vVisited, fLearned );
944  // collect learned clause
945  if ( fLearned )
946  Vec_IntPush( vCore, iThis );
947 }
948 
949 /**Function*************************************************************
950 
951  Synopsis [Computes UNSAT core of the satisfiablity problem.]
952 
953  Description [Takes the interpolation manager, the CNF derived by the SAT
954  solver, which includes the root clauses and the learned clauses. Returns
955  the array of integers representing the number of root clauses that are in
956  the UNSAT core.]
957 
958  SideEffects []
959 
960  SeeAlso []
961 
962 ***********************************************************************/
963 void * Intp_ManUnsatCore( Intp_Man_t * p, Sto_Man_t * pCnf, int fLearned, int fVerbose )
964 {
965  Vec_Int_t * vCore;
966  Vec_Str_t * vVisited;
967  Sto_Cls_t * pClause;
968  int RetValue = 1;
969  abctime clkTotal = Abc_Clock();
970 
971  // check that the CNF makes sense
972  assert( pCnf->nVars > 0 && pCnf->nClauses > 0 );
973  p->pCnf = pCnf;
974  p->fVerbose = fVerbose;
975 
976  // adjust the manager
977  Intp_ManResize( p );
978 
979  // construct proof for each clause
980  // start the proof
981  if ( p->fProofWrite )
982  {
983  p->pFile = fopen( "proof.cnf_", "w" );
984  p->Counter = 0;
985  }
986 
987  // write the root clauses
988 // Vec_IntClear( p->vAnties );
989 // Vec_IntFill( p->vBreaks, p->pCnf->nRoots, 0 );
990  Vec_PtrClear( p->vAntClas );
991  p->nAntStart = p->pCnf->nRoots;
992 
993  Sto_ManForEachClauseRoot( p->pCnf, pClause )
994  Intp_ManProofWriteOne( p, pClause );
995 
996  // propagate root level assignments
997  if ( Intp_ManProcessRoots( p ) )
998  {
999  // if there is no conflict, consider learned clauses
1000  Sto_ManForEachClause( p->pCnf, pClause )
1001  {
1002  if ( pClause->fRoot )
1003  continue;
1004  if ( !Intp_ManProofRecordOne( p, pClause ) )
1005  {
1006  RetValue = 0;
1007  break;
1008  }
1009  }
1010  }
1011 
1012  // add the last breaker
1013 // assert( p->pCnf->pEmpty->Id == Vec_IntSize(p->vBreaks) - 1 );
1014 // Vec_IntPush( p->vBreaks, Vec_IntSize(p->vAnties) );
1015  assert( p->pCnf->pEmpty->Id - p->nAntStart == Vec_PtrSize(p->vAntClas) - 1 );
1016  Vec_PtrPush( p->vAntClas, Vec_IntAlloc(0) );
1017 
1018  // stop the proof
1019  if ( p->fProofWrite )
1020  {
1021  fclose( p->pFile );
1022 // Sat_ProofChecker( "proof.cnf_" );
1023  p->pFile = NULL;
1024  }
1025 
1026  if ( fVerbose )
1027  {
1028 // ABC_PRT( "Core", Abc_Clock() - clkTotal );
1029  printf( "Vars = %d. Roots = %d. Learned = %d. Resol steps = %d. Ave = %.2f. Mem = %.2f MB\n",
1030  p->pCnf->nVars, p->pCnf->nRoots, p->pCnf->nClauses-p->pCnf->nRoots, p->Counter,
1031  1.0*(p->Counter-p->pCnf->nRoots)/(p->pCnf->nClauses-p->pCnf->nRoots),
1032  1.0*Sto_ManMemoryReport(p->pCnf)/(1<<20) );
1033 p->timeTotal += Abc_Clock() - clkTotal;
1034  }
1035 
1036  // derive the UNSAT core
1037  vCore = Vec_IntAlloc( 1000 );
1038  vVisited = Vec_StrStart( p->pCnf->pEmpty->Id+1 );
1039  Intp_ManUnsatCore_rec( p->vAntClas, p->pCnf->pEmpty->Id, vCore, p->pCnf->nRoots, vVisited, fLearned );
1040  Vec_StrFree( vVisited );
1041  if ( fVerbose )
1042  printf( "Root clauses = %d. Learned clauses = %d. UNSAT core size = %d.\n",
1043  p->pCnf->nRoots, p->pCnf->nClauses-p->pCnf->nRoots, Vec_IntSize(vCore) );
1044 // Intp_ManUnsatCoreVerify( p->pCnf, vCore );
1045  return vCore;
1046 }
1047 
1048 /**Function*************************************************************
1049 
1050  Synopsis [Prints learned clauses in terms of original problem varibles.]
1051 
1052  Description []
1053 
1054  SideEffects []
1055 
1056  SeeAlso []
1057 
1058 ***********************************************************************/
1059 void Intp_ManUnsatCorePrintForBmc( FILE * pFile, Sto_Man_t * pCnf, void * vCore0, void * vVarMap0 )
1060 {
1061  Vec_Int_t * vCore = (Vec_Int_t *)vCore0;
1062  Vec_Int_t * vVarMap = (Vec_Int_t *)vVarMap0;
1063  Vec_Ptr_t * vClaMap;
1064  Sto_Cls_t * pClause;
1065  int v, i, iClause, fCompl, iObj, iFrame;
1066  // create map of clause
1067  vClaMap = Vec_PtrAlloc( pCnf->nClauses );
1068  Sto_ManForEachClause( pCnf, pClause )
1069  Vec_PtrPush( vClaMap, pClause );
1070  // print clauses
1071  fprintf( pFile, "UNSAT contains %d learned clauses:\n", Vec_IntSize(vCore) );
1072  Vec_IntForEachEntry( vCore, iClause, i )
1073  {
1074  pClause = (Sto_Cls_t *)Vec_PtrEntry(vClaMap, iClause);
1075  fprintf( pFile, "%6d : %6d : ", i, iClause - pCnf->nRoots );
1076  for ( v = 0; v < (int)pClause->nLits; v++ )
1077  {
1078  fCompl = Abc_LitIsCompl(pClause->pLits[v]);
1079  iObj = Vec_IntEntry(vVarMap, 2*Abc_Lit2Var(pClause->pLits[v]));
1080  iFrame = Vec_IntEntry(vVarMap, 2*Abc_Lit2Var(pClause->pLits[v])+1);
1081  fprintf( pFile, "%s%d(%d) ", fCompl ? "!":"", iObj, iFrame );
1082  }
1083  if ( pClause->nLits == 0 )
1084  fprintf( pFile, "Empty" );
1085  fprintf( pFile, "\n" );
1086  }
1087  Vec_PtrFree( vClaMap );
1088 }
1089 
1090 ////////////////////////////////////////////////////////////////////////
1091 /// END OF FILE ///
1092 ////////////////////////////////////////////////////////////////////////
1093 
1094 
1096 
char * memset()
int Sto_ManMemoryReport(Sto_Man_t *p)
Definition: satStore.c:97
void * Intp_ManUnsatCore(Intp_Man_t *p, Sto_Man_t *pCnf, int fLearned, int fVerbose)
Definition: satInterP.c:963
static int lit_check(lit l, int n)
Definition: satVec.h:149
void Intp_ManPrintClause(Intp_Man_t *p, Sto_Cls_t *pClause)
Definition: satInterP.c:215
void Intp_ManPrintInterOne(Intp_Man_t *p, Sto_Cls_t *pClause)
Definition: satInterP.c:255
int * pProofNums
Definition: satInterP.c:65
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition: vecPtr.h:42
lit * pAssigns
Definition: satInterP.c:54
int nVarsAlloc
Definition: satInterP.c:48
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition: vecVec.h:42
static Llb_Mgr_t * p
Definition: llb3Image.c:950
int sat_solver_addclause(sat_solver *s, lit *begin, lit *end)
Definition: satSolver.c:1492
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition: bblif.c:37
unsigned fRoot
Definition: satStore.h:75
int Counter
Definition: satInterP.c:64
#define l_Undef
Definition: SolverTypes.h:86
static void Intp_ManProofSet(Intp_Man_t *p, Sto_Cls_t *pCls, int n)
Definition: satInterP.c:79
#define ABC_REALLOC(type, obj, num)
Definition: abc_global.h:233
Sto_Cls_t * pEmpty
Definition: satStore.h:91
int nVars
Definition: satStore.h:85
int sat_solver_solve(sat_solver *s, lit *begin, lit *end, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, ABC_INT64_T nConfLimitGlobal, ABC_INT64_T nInsLimitGlobal)
Definition: satSolver.c:1700
static int lit_var(lit l)
Definition: satVec.h:145
int nResLitsAlloc
Definition: satInterP.c:70
lit pLits[0]
Definition: satStore.h:78
int fProofVerif
Definition: satInterP.c:46
Sto_Cls_t * pNext1
Definition: satStore.h:72
Sto_Man_t * pCnf
Definition: satInterP.c:43
void sat_solver_delete(sat_solver *s)
Definition: satSolver.c:1141
static Sto_Cls_t * Intp_ManPropagateOne(Intp_Man_t *p, lit Lit)
Definition: satInterP.c:349
int nTrailSize
Definition: satInterP.c:52
char * memcpy()
int nClausesA
Definition: satStore.h:88
static void Vec_PtrPush(Vec_Ptr_t *p, void *Entry)
Definition: vecPtr.h:606
#define l_True
Definition: SolverTypes.h:84
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static abctime Abc_Clock()
Definition: abc_global.h:279
static int Vec_PtrSize(Vec_Ptr_t *p)
Definition: vecPtr.h:295
static void Vec_VecFree(Vec_Vec_t *p)
Definition: vecVec.h:347
for(p=first;p->value< newval;p=p->next)
unsigned nLits
Definition: satStore.h:77
int lit
Definition: satVec.h:130
FILE * pFile
Definition: satInterP.c:66
Intp_Man_t * Intp_ManAlloc()
FUNCTION DEFINITIONS ///.
Definition: satInterP.c:96
static lit lit_neg(lit l)
Definition: satVec.h:144
void Intp_ManFree(Intp_Man_t *p)
Definition: satInterP.c:178
static void Vec_StrWriteEntry(Vec_Str_t *p, int i, char Entry)
Definition: vecStr.h:370
abctime timeTrace
Definition: satInterP.c:73
static int Abc_LitIsCompl(int Lit)
Definition: abc_global.h:265
Sto_Cls_t * pNext0
Definition: satStore.h:71
static char Vec_StrEntry(Vec_Str_t *p, int i)
Definition: vecStr.h:336
abctime timeTotal
Definition: satInterP.c:74
static Vec_Int_t * Vec_IntAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: bblif.c:149
static void * Vec_PtrEntryLast(Vec_Ptr_t *p)
Definition: vecPtr.h:413
static void Vec_StrFree(Vec_Str_t *p)
Definition: bblif.c:616
static int Vec_IntEntry(Vec_Int_t *p, int i)
Definition: bblif.c:268
lit * pTrail
Definition: satInterP.c:53
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
Sto_Cls_t * Intp_ManPropagate(Intp_Man_t *p, int Start)
Definition: satInterP.c:418
int nAntStart
Definition: satInterP.c:62
static Vec_Str_t * Vec_StrStart(int nSize)
Definition: vecStr.h:95
static void Vec_IntPush(Vec_Int_t *p, int Entry)
Definition: bblif.c:468
int nResLits
Definition: satInterP.c:69
static int Counter
Vec_Ptr_t * vAntClas
Definition: satInterP.c:61
int fVerbose
Definition: satInterP.c:45
int Id
Definition: satStore.h:73
void Intp_ManPrintResolvent(lit *pResLits, int nResLits)
Definition: satInterP.c:235
int Intp_ManProofRecordOne(Intp_Man_t *p, Sto_Cls_t *pClause)
Definition: satInterP.c:668
static int Intp_ManEnqueue(Intp_Man_t *p, lit Lit, Sto_Cls_t *pReason)
Definition: satInterP.c:300
Sto_Cls_t ** pReasons
Definition: satInterP.c:56
char * pSeens
Definition: satInterP.c:55
int Intp_ManProofTraceOne(Intp_Man_t *p, Sto_Cls_t *pConflict, Sto_Cls_t *pFinal)
Definition: satInterP.c:473
static int Intp_ManProofGet(Intp_Man_t *p, Sto_Cls_t *pCls)
Definition: satInterP.c:78
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
static void * Vec_PtrEntry(Vec_Ptr_t *p, int i)
Definition: vecPtr.h:362
abctime timeBcp
Definition: satInterP.c:72
Sto_Cls_t * pTail
Definition: satStore.h:90
void Intp_ManUnsatCore_rec(Vec_Ptr_t *vAntClas, int iThis, Vec_Int_t *vCore, int nRoots, Vec_Str_t *vVisited, int fLearned)
Definition: satInterP.c:919
sat_solver * sat_solver_new(void)
Definition: satSolver.c:1001
static int Vec_IntSize(Vec_Int_t *p)
Definition: bblif.c:252
Sto_Cls_t ** pWatches
Definition: satInterP.c:57
static Vec_Ptr_t * Vec_PtrAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: vecPtr.h:83
static void Intp_ManWatchClause(Intp_Man_t *p, Sto_Cls_t *pClause, lit Lit)
Definition: satInterP.c:275
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define ABC_PRT(a, t)
Definition: abc_global.h:220
void Intp_ManProofWriteOne(Intp_Man_t *p, Sto_Cls_t *pClause)
Definition: satInterP.c:448
int nClauses
Definition: satStore.h:87
int Intp_ManProcessRoots(Intp_Man_t *p)
Definition: satInterP.c:782
static int Abc_Lit2Var(int Lit)
Definition: abc_global.h:264
int Var
Definition: SolverTypes.h:42
lit * pResLits
Definition: satInterP.c:68
#define assert(ex)
Definition: util_old.h:213
static void Intp_ManCancelUntil(Intp_Man_t *p, int Level)
Definition: satInterP.c:323
static void Vec_PtrClear(Vec_Ptr_t *p)
Definition: vecPtr.h:545
#define Sto_ManForEachClause(p, pCls)
Definition: satStore.h:99
#define Sto_ManForEachClauseRoot(p, pCls)
Definition: satStore.h:100
int fProofWrite
Definition: satInterP.c:47
int nRoots
Definition: satStore.h:86
int nClosAlloc
Definition: satInterP.c:49
void Intp_ManUnsatCorePrintForBmc(FILE *pFile, Sto_Man_t *pCnf, void *vCore0, void *vVarMap0)
Definition: satInterP.c:1059
ABC_INT64_T abctime
Definition: abc_global.h:278
unsigned fA
Definition: satStore.h:74
void Intp_ManUnsatCoreVerify(Sto_Man_t *pCnf, Vec_Int_t *vCore)
Definition: satInterP.c:859
int nRootSize
Definition: satInterP.c:51
void Intp_ManResize(Intp_Man_t *p)
Definition: satInterP.c:127
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition: vecInt.h:54
static ABC_NAMESPACE_IMPL_START const lit LIT_UNDEF
DECLARATIONS ///.
Definition: satInterP.c:37
static void Vec_PtrFree(Vec_Ptr_t *p)
Definition: vecPtr.h:223
static int lit_print(lit l)
Definition: satVec.h:147