ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
satInterP.c
Go to the documentation of this file.
1
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
35
36// variable assignments
37static 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
78static inline int Intp_ManProofGet( Intp_Man_t * p, Sto_Cls_t * pCls ) { return p->pProofNums[pCls->Id]; }
79static inline void Intp_ManProofSet( Intp_Man_t * p, Sto_Cls_t * pCls, int n ) { p->pProofNums[pCls->Id] = n; }
80
84
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
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 );
142 p->pReasons = ABC_REALLOC(Sto_Cls_t *, p->pReasons, 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
179{
180/*
181 printf( "Runtime stats:\n" );
182ABC_PRT( "BCP ", p->timeBcp );
183ABC_PRT( "Trace ", p->timeTrace );
184ABC_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
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
235void 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
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
275static 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
300static 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
323static 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
349static 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
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 {
428p->timeBcp += Abc_Clock() - clk;
429 return pClause;
430 }
431 }
432p->timeBcp += Abc_Clock() - clk;
433 return NULL;
434}
435
436
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
473int 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 )
550 Intp_ManPrintResolvent( p->pResLits, p->nResLits );
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 )
603 Intp_ManPrintResolvent( p->pResLits, p->nResLits );
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 );
617 Intp_ManPrintResolvent( p->pResLits, p->nResLits );
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 }
642p->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
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) );
687 Vec_PtrPush( p->vAntClas, Vec_IntAlloc(0) );
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
723 Intp_ManCancelUntil( p, p->nRootSize );
724// Vec_IntPush( p->vBreaks, Vec_IntSize(p->vAnties) );
725 Vec_PtrPush( p->vAntClas, Vec_IntAlloc(0) );
726 return 1;
727 }
728 }
729
730 // construct the proof
731 Intp_ManProofTraceOne( p, pConflict, pClause );
732
733 // undo to the root level
734 Intp_ManCancelUntil( p, p->nRootSize );
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 )
758 Vec_PtrPush( p->vAntClas, Vec_IntAlloc(0) );
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
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
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
919void 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
963void * 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) );
1033p->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
1059void 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
1093
1094
1096
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_PRT(a, t)
Definition abc_global.h:255
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_REALLOC(type, obj, num)
Definition abc_global.h:268
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
struct Vec_Str_t_ Vec_Str_t
Definition bblif.c:46
#define l_True
Definition bmcBmcS.c:35
#define l_Undef
Definition bmcBmcS.c:34
#define sat_solver_addclause
Definition cecSatG2.c:37
#define sat_solver
Definition cecSatG2.c:34
#define sat_solver_solve
Definition cecSatG2.c:45
Cube * p
Definition exorList.c:222
int Var
Definition exorList.c:228
void * Intp_ManUnsatCore(Intp_Man_t *p, Sto_Man_t *pCnf, int fLearned, int fVerbose)
Definition satInterP.c:963
void Intp_ManFree(Intp_Man_t *p)
Definition satInterP.c:178
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
void Intp_ManUnsatCoreVerify(Sto_Man_t *pCnf, Vec_Int_t *vCore)
Definition satInterP.c:859
void Intp_ManPrintResolvent(lit *pResLits, int nResLits)
Definition satInterP.c:235
void Intp_ManResize(Intp_Man_t *p)
Definition satInterP.c:127
void Intp_ManPrintClause(Intp_Man_t *p, Sto_Cls_t *pClause)
Definition satInterP.c:215
int Intp_ManProofTraceOne(Intp_Man_t *p, Sto_Cls_t *pConflict, Sto_Cls_t *pFinal)
Definition satInterP.c:473
void Intp_ManProofWriteOne(Intp_Man_t *p, Sto_Cls_t *pClause)
Definition satInterP.c:448
void Intp_ManUnsatCorePrintForBmc(FILE *pFile, Sto_Man_t *pCnf, void *vCore0, void *vVarMap0)
Definition satInterP.c:1059
Sto_Cls_t * Intp_ManPropagate(Intp_Man_t *p, int Start)
Definition satInterP.c:418
Intp_Man_t * Intp_ManAlloc()
FUNCTION DEFINITIONS ///.
Definition satInterP.c:96
int Intp_ManProofRecordOne(Intp_Man_t *p, Sto_Cls_t *pClause)
Definition satInterP.c:668
int Intp_ManProcessRoots(Intp_Man_t *p)
Definition satInterP.c:782
void Intp_ManPrintInterOne(Intp_Man_t *p, Sto_Cls_t *pClause)
Definition satInterP.c:255
sat_solver * sat_solver_new(void)
Definition satSolver.c:1137
void sat_solver_delete(sat_solver *s)
Definition satSolver.c:1341
int Sto_ManMemoryReport(Sto_Man_t *p)
Definition satStore.c:97
struct Intp_Man_t_ Intp_Man_t
Definition satStore.h:142
#define Sto_ManForEachClause(p, pCls)
Definition satStore.h:99
struct Sto_Man_t_ Sto_Man_t
Definition satStore.h:81
struct Sto_Cls_t_ Sto_Cls_t
BASIC TYPES ///.
Definition satStore.h:67
#define Sto_ManForEachClauseRoot(p, pCls)
Definition satStore.h:100
int lit
Definition satVec.h:130
int fProofWrite
Definition satInterP.c:47
int nVarsAlloc
Definition satInterP.c:48
lit * pResLits
Definition satInterP.c:68
Sto_Cls_t ** pReasons
Definition satInterP.c:56
Sto_Cls_t ** pWatches
Definition satInterP.c:57
int * pProofNums
Definition satInterP.c:65
abctime timeTrace
Definition satInterP.c:73
abctime timeBcp
Definition satInterP.c:72
lit * pAssigns
Definition satInterP.c:54
Sto_Man_t * pCnf
Definition satInterP.c:43
int nResLitsAlloc
Definition satInterP.c:70
int nClosAlloc
Definition satInterP.c:49
abctime timeTotal
Definition satInterP.c:74
int fProofVerif
Definition satInterP.c:46
int nAntStart
Definition satInterP.c:62
lit * pTrail
Definition satInterP.c:53
FILE * pFile
Definition satInterP.c:66
int nTrailSize
Definition satInterP.c:52
Vec_Ptr_t * vAntClas
Definition satInterP.c:61
int nRootSize
Definition satInterP.c:51
char * pSeens
Definition satInterP.c:55
lit pLits[0]
Definition satStore.h:78
unsigned fA
Definition satStore.h:74
unsigned nLits
Definition satStore.h:77
Sto_Cls_t * pNext1
Definition satStore.h:72
unsigned fRoot
Definition satStore.h:75
Sto_Cls_t * pNext0
Definition satStore.h:71
int nVars
Definition satStore.h:85
int nRoots
Definition satStore.h:86
int nClauses
Definition satStore.h:87
#define assert(ex)
Definition util_old.h:213
char * memcpy()
char * memset()
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition vecVec.h:42