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