source: vis_dev/vis-2.3/src/sat/satCore.c @ 40

Last change on this file since 40 was 14, checked in by cecile, 13 years ago

vis2.3

File size: 39.3 KB
Line 
1/**CFile***********************************************************************
2
3  FileName    [satCore.c]
4
5  PackageName [sat]
6
7  Synopsis    [Routines for UNSAT core generation,both CNF-based and Aig-based
8              UNSAT core generetions are available]
9
10  Author      [Bing Li]
11
12  Copyright [ This file was created at the University of Colorado at
13  Boulder.  The University of Colorado at Boulder makes no warranty
14  about the suitability of this software for any purpose.  It is
15  presented on an AS IS basis.]
16
17
18******************************************************************************/
19
20#include "satInt.h"
21#include "puresatInt.h"
22
23static char rcsid[] UNUSED = "$Id: satCore.c,v 1.20 2009/04/12 00:14:11 fabio Exp $";
24
25/*---------------------------------------------------------------------------*/
26/* Constant declarations                                                     */
27/*---------------------------------------------------------------------------*/
28
29#define CONFLICT 1
30#define NO_CONFLICT 2
31/**AutomaticStart*************************************************************/
32
33/*---------------------------------------------------------------------------*/
34/* Static function prototypes                                                */
35/*---------------------------------------------------------------------------*/
36
37static int
38ScoreCompare(
39  const void * node1,
40  const void * node2)
41{
42int v1;
43int v2;
44int s1, s2;
45
46  v1 = *(int *)(node1);
47  v2 = *(int *)(node2);
48  s1 = *((int *)(node1) + 1);
49  s2 = *((int *)(node2) + 1);
50
51  if(s1 == s2) {
52    return(v1 > v2);
53  }
54  return(s1 < s2);
55}
56
57/**AutomaticEnd***************************************************************/
58
59
60/*---------------------------------------------------------------------------*/
61
62/* Definition of exported functions                                          */
63/*---------------------------------------------------------------------------*/
64
65
66/**Function********************************************************************
67
68  Synopsis    [Print literals of given clauses]
69
70  Description [Print literals of given clauses]
71
72  SideEffects [ ]
73
74  SeeAlso     [ ]
75
76******************************************************************************/
77
78void
79sat_PrintClauseLits(satManager_t * cm,
80                       long concl)
81{
82  long i, node, var_idx,*lit;
83
84  for(i=0, lit = (long*)SATfirstLit(concl); i<SATnumLits(concl);i++, lit++){
85    node = SATgetNode(*lit);
86    var_idx = SATnodeID(node);
87    if(SATisInverted(node))
88      fprintf(vis_stdout,"%ld ", -var_idx);
89    else
90      fprintf(vis_stdout,"%ld ",var_idx);
91  }
92  fprintf(vis_stdout,"0\n");
93}
94
95
96/**Function********************************************************************
97
98  Synopsis    [Print literals of given clauses to a certain file for UNSAT
99               core generation]
100
101  Description [Print literals of given clauses to a certain file for UNSAT
102               core generation]
103
104  SideEffects [ ]
105
106  SeeAlso     [ ]
107
108******************************************************************************/
109
110void
111sat_PrintClauseLitsForCore(satManager_t * cm,
112                       long concl,
113                       FILE *fp)
114{
115  long i, node, var_idx,*lit, cls_idx;
116
117  lit = (long*)SATfirstLit(concl);
118  cls_idx = -(*(lit-1));
119
120  if(fp) {
121    /** cls_idx -= cm->numOfVar * satNodeSize; **/
122    cls_idx -= cm->initNumVariables * satNodeSize;
123    /**cls idx starts from 0 **/
124    cls_idx = cls_idx/satNodeSize - 1;
125    fprintf(fp,"#clause index:%ld\n",cls_idx);
126    for(i=0, lit = (long*)SATfirstLit(concl); i<SATnumLits(concl);i++, lit++){
127      node = SATgetNode(*lit);
128      var_idx = SATnodeID(node);
129      if(SATisInverted(node))
130        fprintf(fp, "%ld ", -var_idx);
131      else
132        fprintf(fp, "%ld ",var_idx);
133    }
134    fprintf(fp, "0\n");
135  }
136  else {
137    if(cm->clauseIndexInCore == 0)
138      cm->clauseIndexInCore = sat_ArrayAlloc(1024);
139    sat_ArrayInsert(cm->clauseIndexInCore, cls_idx);
140  }
141
142}
143
144
145/**Function********************************************************************
146
147  Synopsis    [Recursively generate the UNSAT core]
148
149  Description [Recursively generate the UNSAT core]
150
151  SideEffects [ ]
152
153  SeeAlso     [ ]
154
155******************************************************************************/
156
157void
158sat_GenerateCoreRecur(satManager_t * cm,
159                 long concl,
160                 FILE *fp,
161                 int * count)
162{
163  int j;
164  long tmp;
165  satArray_t * dep;
166
167  if(!(SATflags(concl)&NewMask)){
168    SATflags(concl)|=NewMask;
169    /** Not Conflict **/
170    if(!(SATflags(concl)& IsConflictMask)){
171      (*count)++;
172      sat_PrintClauseLitsForCore(cm,concl,fp);
173    }
174    /** is CONFLICT **/
175    else{
176      if(!st_lookup(cm->dependenceTable,(char *)concl, &dep)){
177        fprintf(cm->stdOut,"%ld is not in depe table\n",concl);
178        exit(0);
179      }
180      else{
181        for(j=0;j<dep->num; j++){
182          tmp = dep->space[j];
183          sat_GenerateCoreRecur(cm, tmp, fp, count);
184        }
185      }
186    }
187  }/**  if(!(SATflags(concl)&NewMask)){ **/
188}
189
190
191
192/**Function********************************************************************
193
194  Synopsis    [Generate dependence clauses for the conflict]
195
196  Description [Generate dependence clauses for the conflict]
197
198  SideEffects [ ]
199
200  SeeAlso     [ ]
201
202******************************************************************************/
203
204void
205sat_GetDependence(satManager_t * cm, long concl, satArray_t* dep)
206{
207long node, *lit, ante;
208int i;
209
210  for(i=0, lit = (long*)SATfirstLit(concl); i<SATnumLits(concl);i++, lit++){
211    node = SATgetNode(*lit);
212    node = SATnormalNode(node);
213    ante = SATante(node);
214    if(ante==0){
215      if(!st_lookup(cm->anteTable, (char *)node, &ante)){
216        fprintf(vis_stdout,"ante = 0 and is not in anteTable %ld\n",node);
217        exit(0);
218      }
219    }
220    if(!(SATflags(ante)&NewMask)){
221      SATflags(ante)|=NewMask;
222      sat_ArrayInsert(dep,ante);
223      sat_GetDependence(cm,ante,dep);
224    }
225  }
226}
227
228/**Function********************************************************************
229
230  Synopsis    [Conflict Core Generation]
231
232  Description [Conflict Core Generation]
233
234  SideEffects [ ]
235
236  SeeAlso     [ ]
237
238******************************************************************************/
239
240void
241sat_GenerateCore(satManager_t * cm)
242{
243  int j, tmp,value;
244  long *lit, node, concl, i;
245  satArray_t * dep;
246  FILE *fp = cm->fp;
247  int  count, inverted;
248  st_generator *stGen;
249  satArray_t* tmpdep = sat_ArrayAlloc(1);
250  satLevel_t * d;
251
252  cm->status = 0;
253  count = 0;
254  d = SATgetDecision(0);
255  for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize){
256    node = i;
257    if((SATflags(node)&IsCNFMask)&&(SATnumLits(node)==1)){
258      lit = (long*)SATfirstLit(node);
259      tmp = SATgetNode(*lit);
260      inverted = SATisInverted(tmp);
261      tmp = SATnormalNode(tmp);
262
263
264      value = !inverted;
265      if(SATvalue(tmp) < 2)     {
266        if(SATvalue(tmp) == value)      continue;
267        else {
268          cm->status = SAT_UNSAT;
269          d->conflict = node;
270          break;
271        }
272      }
273
274      SATvalue(tmp) = !inverted;
275      SATmakeImplied(tmp, d);
276      SATante(tmp) = node;
277      if((SATflags(tmp) & InQueueMask) == 0) {
278        sat_Enqueue(cm->queue, tmp);
279        SATflags(tmp) |= InQueueMask;
280      }
281      /** sat_ArrayInsert(unitArray, tmp); **/
282    }
283  }
284
285  sat_ImplicationMain(cm, d);
286  if(d->conflict == 0) {
287    fprintf(vis_stderr,"There should be a conflict\n");
288    exit(0);
289  }
290  /** Last Conflict Cls **/
291  concl = d->conflict;
292  sat_ArrayInsert(tmpdep,concl);
293  SATflags(concl)|=NewMask;
294  /** sat_ArrayInsert(arr,cl); **/
295  if(!(SATflags(concl)&IsConflictMask)){
296    count++;
297    sat_PrintClauseLitsForCore(cm,concl,fp);
298  }
299
300  sat_GetDependence(cm, concl, tmpdep);
301  for(i=satNodeSize;i<cm->nodesArraySize;i+=satNodeSize){
302    SATflags(i)&=ResetNewMask;
303  }
304
305  for(i=0;i<tmpdep->num;i++){
306    concl = tmpdep->space[i];
307    if(!(SATflags(concl)&NewMask)){
308      SATflags(concl)|=NewMask;
309      /** is CONFLICT **/
310      if((SATflags(concl)&IsConflictMask)){
311        if(!st_lookup(cm->dependenceTable,(char *)concl,&dep)){
312          fprintf(cm->stdOut,"%ld is conflict but not in depe table\n",concl);
313          exit(0);
314        }
315        else{
316          for(j=0;j<dep->num; j++){
317            tmp = dep->space[j];
318            sat_GenerateCoreRecur(cm, tmp, fp, &count);
319          }
320        }
321      }
322      /**not CONFLICT **/
323      else{
324        count++;
325        sat_PrintClauseLitsForCore(cm,concl,fp);
326      }
327    }
328  }
329  /**fclose(fp); **/
330  cm->numOfClsInCore = count;
331
332  for(i=satNodeSize;i<cm->nodesArraySize;i+=satNodeSize){
333    SATflags(i)&=ResetNewMask;
334  }
335  st_foreach_item(cm->dependenceTable, stGen,&node, &dep)
336    sat_ArrayFree(dep);
337  sat_ArrayFree(tmpdep);
338  sat_Undo(cm,d);
339  st_free_table(cm->dependenceTable);
340  st_free_table(cm->anteTable);
341  cm->status = SAT_UNSAT;
342}
343
344/**Function********************************************************************
345
346  Synopsis    [Implication propogation from assertations in an array ]
347
348  Description [This funct is only for AIG assertation]
349
350  SideEffects []
351
352  SeeAlso     []
353
354******************************************************************************/
355void
356sat_ImplyArrayWithAnte(
357        satManager_t *cm,
358        satLevel_t *d,
359        satArray_t *arr)
360{
361int i, size;
362bAigEdge_t v;
363int inverted, value;
364satQueue_t *Q;
365
366  if(arr == 0)  return;
367  if(cm->status)return;
368
369  size = arr->num;
370  Q = cm->queue;
371  for(i=0; i<size; i++) {
372    v = arr->space[i];
373    inverted = SATisInverted(v);
374    v = SATnormalNode(v);
375
376    value = !inverted;
377    if(SATvalue(v) < 2) {
378      if(SATvalue(v) == value)  continue;
379      else {
380        cm->status = SAT_UNSAT;
381        d->conflict = v;
382        return;
383      }
384    }
385
386    SATvalue(v) = value;
387    SATmakeImplied(v, d);
388    SATante(v) = SATnormalNode(v);
389
390    if((SATflags(v) & InQueueMask) == 0) {
391      sat_Enqueue(Q, v);
392      SATflags(v) |= InQueueMask;
393    }
394  }
395}
396
397
398/**Function********************************************************************
399
400  Synopsis    [Force implication to pure and unit literals and set antecedence
401              of them]
402
403  Description [Force implication to pure and unit literals and set antecedence
404              of them]
405
406  SideEffects [ ]
407
408  SeeAlso     [ ]
409
410******************************************************************************/
411void
412sat_ImplyUnitPureLitsWithAnte(satManager_t * cm, satLevel_t *d)
413{
414  int tmp, inverted;
415  long node, *lit, i;
416
417  for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize){
418    node = i;
419    if((SATflags(node)&IsCNFMask)&&(SATnumLits(node)==1)){
420      int value;
421      lit = (long*)SATfirstLit(node);
422      tmp = SATgetNode(*lit);
423      inverted = SATisInverted(tmp);
424      tmp = SATnormalNode(tmp);
425
426      value = !inverted;
427      if(SATvalue(tmp) < 2)     {
428        if(SATvalue(tmp) == value)      continue;
429        else {
430          cm->status = SAT_UNSAT;
431          d->conflict = node;
432          break;
433        }
434      }
435
436      SATvalue(tmp) = !inverted;
437      SATmakeImplied(tmp, d);
438      SATante(tmp) = node;
439      if((SATflags(tmp) & InQueueMask) == 0) {
440        sat_Enqueue(cm->queue, tmp);
441        SATflags(tmp) |= InQueueMask;
442      }
443    }
444  }
445
446  if(cm->status == SAT_UNSAT)
447    return;
448
449  sat_ImplyArray(cm, d, cm->pureLits);
450}
451
452
453/**Function********************************************************************
454
455  Synopsis    [Build an node for resolution tree]
456
457  Description [tmpIP, lp,size must be prepared
458               Get formula for leaf nodes]
459
460  SideEffects []
461
462  SeeAlso     []
463
464******************************************************************************/
465void
466sat_BuildRT(
467  satManager_t * cm,
468  RTnode_t root,
469  long *lp,
470  long *tmpIP,
471  int size,
472  boolean NotCNF)
473{
474  int i;
475  long tmpnode;
476  RTManager_t *rm = cm->rm;
477
478  RT_formula(root) = rm->cpos;
479
480  RT_fSize(root) = size;
481
482
483  if(rm->maxpos<=rm->cpos+size+1){
484    rm->fArray = REALLOC(long,rm->fArray,rm->maxpos+FORMULA_BLOCK);
485    rm->maxpos = rm->maxpos+FORMULA_BLOCK;
486  }
487
488  for(i=0;i<size;i++,lp++){
489    if(NotCNF)
490      tmpnode = *lp;
491    else
492      tmpnode = SATgetNode(*lp);
493    rm->fArray[rm->cpos] = tmpnode;
494    rm->cpos++;
495  }
496}
497
498/**Function********************************************************************
499
500  Synopsis    [Generate interpolation forwardly]
501
502  Description []
503
504  SideEffects []
505
506  SeeAlso     []
507
508******************************************************************************/
509
510bAigEdge_t sat_GenerateFwdIP(bAig_Manager_t* manager,
511                             satManager_t *cm,
512                             RTnode_t  RTnode,
513                             int cut)
514{
515  int i;
516  long node, node1, left, right, result, *lp, *lp1;
517  int IPTrue=0, local=1, first=0, second=0, allDummy=1;
518  RTManager_t * rm = cm->rm;
519
520  manager->class_ = cut;
521  if(RT_flag(RTnode)&RT_VisitedMask){
522#if DBG
523    assert(RT_IPnode(RTnode)!=-1);
524#endif
525
526    return RT_IPnode(RTnode);
527  }
528#if DBG
529  assert(RT_IPnode(RTnode)==-1);
530#endif
531  RT_flag(RTnode) |= RT_VisitedMask;
532
533  if(RT_pivot(RTnode)==0){ /*leaf*/
534
535#if DBG
536    assert(RT_left(RTnode)==RT_NULL&&RT_right(RTnode)==RT_NULL);
537#endif
538
539#if DBG
540    assert(RT_oriClsIdx(RTnode)==0);
541#endif
542    if(RT_oriClsIdx(RTnode))
543      lp = (long*)SATfirstLit(RT_oriClsIdx(RTnode));
544    else
545
546      lp = RT_formula(RTnode) + cm->rm->fArray;
547    lp1 = lp;
548    for(i=0;i<RT_fSize(RTnode);i++,lp++){
549      if(*lp == DUMMY)
550        continue;
551      else{
552        allDummy = 0;
553#if DBG
554        assert(*lp>0);
555#endif
556      }
557      if(RT_oriClsIdx(RTnode))/*is CNF*/
558        node = SATgetNode(*lp);
559      else /*is AIG*/
560        node = *lp;
561
562      node = SATnormalNode(node);
563      if(SATflags(node)&IsGlobalVarMask)
564        continue;
565
566      if(SATclass(node)>cut){
567        IPTrue = 1;
568#if DBG
569        second = 1;
570#else
571        break;
572#endif
573      }
574#if DBG
575      else{
576        first = 1;
577      }
578#endif
579    }
580
581#if DBG
582    assert(!allDummy);
583    assert(!(first&&second));
584#endif
585
586
587    if(IPTrue){
588      RT_IPnode(RTnode) = bAig_One;
589      return bAig_One;
590    }
591
592    lp = lp1;
593    result = bAig_Zero;
594    for(i=0;i<RT_fSize(RTnode);i++,lp++){
595      if(RT_oriClsIdx(RTnode))/*is CNF*/
596        node = SATgetNode(*lp);
597      else /*is AIG*/
598        node = *lp;
599      node1 = SATnormalNode(node);
600      if(flags(node1)&IsGlobalVarMask){
601        result = PureSat_Or(manager,result,node);
602        cm->nodesArray = manager->NodesArray;
603      }
604    }
605
606    RT_IPnode(RTnode) = result;
607    return result;
608  } /*leaf*/
609
610  /*not leaf*/
611  else{
612
613#if DBG
614    assert(RT_left(RTnode)!=RT_NULL&&RT_right(RTnode)!=RT_NULL);
615#endif
616    left = sat_GenerateFwdIP(manager,cm,RT_left(RTnode),cut);
617    right = sat_GenerateFwdIP(manager,cm,RT_right(RTnode),cut);
618    if(RT_pivot(RTnode)<0){
619      int class_;
620      class_ = RT_pivot(RTnode)-DUMMY;
621#if DBG
622      assert(class_>0);
623#endif
624      if(class_>cut)
625        local=0;
626    }
627    else{
628      node = SATnormalNode(RT_pivot(RTnode));
629      if((SATflags(node)&IsGlobalVarMask)||
630         (SATclass(node)>cut))
631        local = 0;
632    }
633    if(local==0){
634      result = PureSat_And(manager,left,right);
635
636    }
637    else{
638      result = PureSat_Or(manager,left,right);
639
640    }
641  }/* else{ not leaf*/
642
643  cm->nodesArray = manager->NodesArray;
644  RT_IPnode(RTnode) = result;
645  return result;
646
647}
648
649
650/**Function********************************************************************
651
652  Synopsis    [Generate interpolation backwardly]
653
654  Description []
655
656  SideEffects []
657
658  SeeAlso     []
659
660******************************************************************************/
661
662
663bAigEdge_t sat_GenerateBwdIP(bAig_Manager_t* manager,
664                             satManager_t *cm,
665                             RTnode_t RTnode,
666                             int cut)
667{
668  int i;
669  long node,node1, left, right, result, *lp, *lp1;
670  int IPTrue=0, local=1, allGV=1;
671  RTManager_t * rm = cm->rm;
672
673  manager->class_ = cut;
674
675  if(RT_flag(RTnode)&RT_VisitedMask){
676#if DBG
677    assert(RT_IPnode(RTnode)!=-1);
678#endif
679
680    return RT_IPnode(RTnode);
681  }
682#if DBG
683  assert(RT_IPnode(RTnode)==-1);
684#endif
685  RT_flag(RTnode) |= RT_VisitedMask;
686
687  if(RT_pivot(RTnode)==0){ /*leaf*/
688
689#if DBG
690    assert(RT_left(RTnode)==RT_NULL&&RT_right(RTnode)==RT_NULL);
691    assert(RT_oriClsIdx(RTnode)==0);
692#endif
693    result = bAig_Zero;
694    if(RT_oriClsIdx(RTnode))
695      lp = (long*)SATfirstLit(RT_oriClsIdx(RTnode));
696    else
697
698      lp = RT_formula(RTnode) + cm->rm->fArray;
699    lp1 = lp;
700    for(i=0;i<RT_fSize(RTnode);i++,lp++){
701      if(*lp == DUMMY)
702        continue;
703      else{
704        assert(*lp>0);
705      }
706      if(RT_oriClsIdx(RTnode))/*is CNF*/
707        node = SATgetNode(*lp);
708      else /*is AIG*/
709        node = *lp;
710      node = SATnormalNode(node);
711      if(SATflags(node)&IsGlobalVarMask)
712        continue;
713      else
714        allGV = 0;
715
716      if(SATclass(node)<=cut){
717          IPTrue = 1;
718          break;
719      }
720    }
721
722    if(IPTrue||allGV){
723      RT_IPnode(RTnode) = bAig_One;
724      return bAig_One;
725    }
726
727    lp = lp1;
728    for(i=0;i<RT_fSize(RTnode);i++,lp++){
729      if(RT_oriClsIdx(RTnode))/*is CNF*/
730        node = SATgetNode(*lp);
731      else /*is AIG*/
732        node = *lp;
733      node1 = SATnormalNode(node);
734      if(SATflags(node1)&IsGlobalVarMask){
735        result = PureSat_Or(manager,result,node);
736        cm->nodesArray = manager->NodesArray;
737      }
738    }
739    RT_IPnode(RTnode)  = result;
740    return result;
741  } /*leaf*/
742
743  /*not leaf*/
744  else{
745
746#if DBG
747    assert(RT_left(RTnode)!=RT_NULL&&RT_right(RTnode)!=RT_NULL);
748#endif
749    left = sat_GenerateBwdIP(manager,cm,RT_left(RTnode),cut);
750    right = sat_GenerateBwdIP(manager,cm,RT_right(RTnode),cut);
751    if(RT_pivot(RTnode)<0){
752      int class_;
753      class_ = RT_pivot(RTnode)-DUMMY;
754#if DBG
755      assert(class_>0);
756#endif
757      if(class_<=cut)
758        local=0;
759    }
760    else{
761      node = SATnormalNode(RT_pivot(RTnode));
762
763      if((SATflags(node)&IsGlobalVarMask)||
764         (SATclass(node)<=cut))
765        local = 0;
766    }
767    if(local==0){
768      result = PureSat_And(manager,left,right);
769
770    }
771    else{
772      result = PureSat_Or(manager,left,right);
773
774    }
775  }/* else{ not leaf*/
776
777  cm->nodesArray = manager->NodesArray;
778  RT_IPnode(RTnode) = result;
779  return result;
780
781}
782
783/**Function********************************************************************
784
785  Synopsis    [ Reset resolution tree]
786
787  Description []
788
789  SideEffects []
790
791  SeeAlso     []
792
793******************************************************************************/
794
795void ResetRTree(RTManager_t *rm)
796{
797  int i;
798  for(i=RTnodeSize;i<=rm->aSize;i+=RTnodeSize){
799    RT_IPnode(i) = -1;
800    RT_flag(i) &= RT_ResetVisitedMask;
801  }
802
803  return;
804}
805
806/**Function********************************************************************
807
808  Synopsis    [Free a resolution tree]
809
810  Description []
811
812  SideEffects []
813
814  SeeAlso     []
815
816******************************************************************************/
817void
818RT_Free(RTManager_t *rm)
819{
820  FREE(rm->nArray);
821  FREE(rm->fArray);
822  FREE(rm);
823}
824
825/**Function********************************************************************
826
827  Synopsis    [Mark nodes in layer associated with property]
828
829  Description []
830
831  SideEffects []
832
833  SeeAlso     []
834
835******************************************************************************/
836void
837sat_MarkLayerProperty(satManager_t *cm,
838                      long v,
839                      int layer)
840{
841  satVariable_t *var = SATgetVariable(v);
842
843  if((v==bAig_NULL))
844    return;
845
846  if(!(SATflags(v)&CoiMask)){
847
848    return;
849  }
850
851  /*already assigned score*/
852  if(SATflags(v)&Visited2Mask){
853
854    return;
855  }
856
857  var->scores[0] = SCOREUNIT*layer;
858  var->scores[1] = SCOREUNIT*layer;
859  SATflags(v) |= Visited2Mask;
860
861
862  if((SATflags(v)&StateBitMask)&&
863     (SATclass(v)<=cm->Length)){
864
865    return;
866  }
867
868  sat_MarkLayerProperty(cm,SATleftChild(v),layer);
869  sat_MarkLayerProperty(cm,SATrightChild(v),layer);
870
871}
872
873/**Function********************************************************************
874
875  Synopsis    [Mark nodes in layers associated normal visible latches]
876
877  Description []
878
879  SideEffects []
880
881  SeeAlso     []
882
883******************************************************************************/
884
885void sat_MarkLayer(satManager_t *cm,
886                   long v,
887                   int layer)
888{
889  satVariable_t *var = SATgetVariable(v);
890
891  if((v==bAig_NULL))
892    return;
893
894  if(!(SATflags(v)&CoiMask)){
895
896    return;
897  }
898
899  /*already assigned score*/
900  if(SATflags(v)&Visited2Mask){
901
902    return;
903  }
904
905  var->scores[0] = SCOREUNIT*layer;
906  var->scores[1] = SCOREUNIT*layer;
907  SATflags(v) |= Visited2Mask;
908
909
910  if((SATflags(v)&StateBitMask)){
911
912    return;
913  }
914
915  sat_MarkLayer(cm,SATleftChild(v),layer);
916  sat_MarkLayer(cm,SATrightChild(v),layer);
917
918}
919
920/**Function********************************************************************
921
922  Synopsis    [Mark nodes in layers associated with initial states]
923
924  Description []
925
926  SideEffects []
927
928  SeeAlso     []
929
930******************************************************************************/
931
932
933void sat_MarkLayerInitState(satManager_t *cm,
934                            long v,
935                            int layer)
936{
937  satVariable_t *var = SATgetVariable(v);
938
939  if((v==bAig_NULL))
940    return;
941
942  if(!(SATflags(v)&CoiMask)){
943
944    return;
945  }
946
947  /*already assigned score*/
948  if(SATflags(v)&Visited2Mask){
949
950    return;
951  }
952
953  var->scores[0] = SCOREUNIT*layer;
954  var->scores[1] = SCOREUNIT*layer;
955  SATflags(v) |= Visited2Mask;
956
957
958  /*if((SATflags(v)&StateBitMask)){
959    fprintf(vis_stderr,"%d ISV return\n",SATnormalNode(v));
960    return;
961    }*/
962
963  sat_MarkLayerInitState(cm,SATleftChild(v),layer);
964  sat_MarkLayerInitState(cm,SATrightChild(v),layer);
965
966}
967
968/**Function********************************************************************
969
970  Synopsis    [Mark nodes in layers of a certain latch aig nodes]
971
972  Description []
973
974  SideEffects []
975
976  SeeAlso     []
977
978******************************************************************************/
979
980void sat_MarkLayerLatch(satManager_t *cm,
981                        long v,
982                        int layer)
983{
984  satVariable_t *var = SATgetVariable(v);
985
986  if((v==bAig_NULL))
987    return;
988
989  if(!(SATflags(v)&CoiMask)){
990
991    return;
992  }
993
994  /*not assigned score yet*/
995  if(!(SATflags(v)&Visited2Mask)){
996    var->scores[0] = SCOREUNIT*layer;
997    var->scores[1] = SCOREUNIT*layer;
998    SATflags(v) |= Visited2Mask;
999
1000  }
1001  sat_MarkLayer(cm,SATleftChild(v),layer);
1002  sat_MarkLayer(cm,SATrightChild(v),layer);
1003
1004}
1005
1006/**Function********************************************************************
1007
1008  Synopsis    [layer score initialization]
1009
1010  Description []
1011
1012  SideEffects []
1013
1014  SeeAlso     []
1015
1016******************************************************************************/
1017
1018void sat_InitLayerScore(satManager_t * cm){
1019  int i,j,k,layer;
1020  long v;
1021  st_table *table;
1022  st_generator * stgen, *stgen1;
1023  satVariable_t *var;
1024
1025  int objExist;
1026  int inverted;
1027  long *plit, nv;
1028  int size;
1029  int count0, count1;
1030  satArray_t *ordered, *newOrdered;
1031  array_t * layerArray = array_alloc(st_table *,cm->LatchLevel+1);
1032
1033  for(k=1;k<=cm->LatchLevel;k++){
1034      cm->assignedArray[k]=0;
1035      cm->numArray[k]=0;
1036  }
1037
1038  cm->currentLevel = cm->LatchLevel;
1039
1040  for(i=satNodeSize;i<cm->nodesArraySize;i+=satNodeSize){
1041    SATflags(i)&=ResetVisited2Mask;
1042  }
1043
1044
1045  sat_MarkLayerInitState(cm,cm->InitState,cm->LatchLevel);
1046
1047  sat_MarkLayerProperty(cm,cm->property,cm->LatchLevel);
1048
1049
1050  st_foreach_item(cm->layerTable,stgen,&table,&layer)
1051    array_insert(st_table *,layerArray,layer,table);
1052
1053  for(i=cm->LatchLevel;i>=1;i--){
1054    table = array_fetch(st_table*,layerArray,i);
1055    st_foreach_item(table,stgen1,&v,NIL(char*)){
1056      sat_MarkLayerLatch(cm,v,i);
1057
1058    }
1059  }
1060
1061  array_free(layerArray);
1062
1063  for(i=bAigNodeSize;i<cm->nodesArraySize;i+=bAigNodeSize){
1064    if(SATflags(i)&Visited2Mask){
1065      int layer;
1066      SATflags(i)&=ResetVisited2Mask;
1067      var = SATgetVariable(i);
1068#if DBG
1069      assert(var->scores[0]%SCOREUNIT==0);
1070#endif
1071      layer = var->scores[0]/SCOREUNIT;
1072      cm->numArray[layer]++;
1073    }
1074  }
1075
1076  if(cm->option->verbose >= 2){
1077    for(i=1;i<=cm->LatchLevel;i++){
1078      fprintf(vis_stdout,"Level %d:%d\n",i,cm->numArray[i]);
1079    }
1080  }
1081
1082
1083  ordered = cm->orderedVariableArray;
1084  if(ordered == 0)
1085    ordered = sat_ArrayAlloc(cm->initNumVariables);
1086  else
1087    ordered->num = 0;
1088  cm->orderedVariableArray = ordered;
1089
1090  objExist = 0;
1091
1092
1093  for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize) {
1094    v = i;
1095    if((SATflags(v) & IsBDDMask)) {
1096      continue;
1097    }
1098    if((SATflags(v) & IsCNFMask)) {
1099      size = SATnumLits(v);
1100      plit = (long*)SATfirstLit(v);
1101      for(j=0; j<size; j++, plit++) {
1102        nv = SATgetNode(*plit);
1103        inverted = !(SATisInverted(nv));
1104        nv = SATnormalNode(nv);
1105        var = SATgetVariable(nv);
1106        var->litsCount[inverted]++;
1107      }
1108      continue;
1109    }
1110    if(!(SATflags(v) & CoiMask))        continue;
1111    if(!(SATflags(v) & VisitedMask) && objExist)        continue;
1112
1113    if(SATvalue(v) != 2 && SATlevel(v) == 0)    continue;
1114
1115    count0 = count1 = SATnFanout(v);
1116    if(count0 == 0 && SATleftChild(v) == 2 && SATrightChild(v) == 2) {
1117      count0 = 0;
1118      count1 = 0;
1119    }
1120    else if(SATleftChild(v) != 2) {
1121      count0 += 2;
1122      count1++;
1123    }
1124    else {
1125      count0 += 3;
1126      count1 += 3;
1127    }
1128
1129    var = SATgetVariable(v);
1130    var->litsCount[0] += count0;
1131    var->litsCount[1] += count1;
1132
1133    sat_ArrayInsert(ordered, v);
1134  }
1135
1136  for(i=0; i<cm->unitLits->num; i++) {
1137    v = cm->unitLits->space[i];
1138    v = SATnormalNode(v);
1139    SATflags(v) |= NewMask;
1140  }
1141  if(cm->assertion) {
1142    for(i=0; i<cm->assertion->num; i++) {
1143      v = cm->assertion->space[i];
1144      v = SATnormalNode(v);
1145      SATflags(v) |= NewMask;
1146    }
1147  }
1148
1149  newOrdered = sat_ArrayAlloc((ordered->num) * 2);
1150  size = ordered->num;
1151  for(i=0; i<size; i++) {
1152    v = ordered->space[i];
1153    var = SATgetVariable(v);
1154    var->lastLitsCount[0] = var->litsCount[0];
1155    var->lastLitsCount[1] = var->litsCount[1];
1156    var->scores[0] += var->lastLitsCount[0];
1157    var->scores[1] += var->lastLitsCount[1];
1158
1159    if(SATflags(v) & NewMask);
1160    else if(var->scores[0] == 0 && var->scores[1] == 0 && !(SATflags(v) & NewMask)) {
1161      sat_ArrayInsert(cm->pureLits, (v));
1162    }
1163    else if(var->scores[0] == 0 && !(SATflags(v) & NewMask)) {
1164      sat_ArrayInsert(cm->pureLits, (v));
1165    }
1166    else if(var->scores[1] == 0 && !(SATflags(v) & NewMask)) {
1167      sat_ArrayInsert(cm->pureLits, SATnot(v));
1168    }
1169    else {
1170      sat_ArrayInsert(newOrdered, v);
1171      sat_ArrayInsert(newOrdered, (var->scores[0] > var->scores[1]) ? var->scores[0] : var->scores[1]);
1172    }
1173  }
1174
1175  for(i=0; i<cm->unitLits->num; i++) {
1176    v = cm->unitLits->space[i];
1177    v = SATnormalNode(v);
1178    SATflags(v) &= ResetNewMask;
1179  }
1180  if(cm->assertion) {
1181    for(i=0; i<cm->assertion->num; i++) {
1182      v = cm->assertion->space[i];
1183      v = SATnormalNode(v);
1184      SATflags(v) &= ResetNewMask;
1185    }
1186  }
1187
1188  cm->orderedVariableArray = ordered;
1189  size = newOrdered->num;
1190  qsort(newOrdered->space, size>>1, sizeof(long)*2, ScoreCompare);
1191
1192  cm->currentVarPos = 0;
1193  ordered->num = 0;
1194  for(i=0; i<size; i++) {
1195    v = newOrdered->space[i];
1196    var = SATgetVariable(v);
1197    var->pos = (i>>1);
1198    sat_ArrayInsert(ordered, v);
1199    i++;
1200  }
1201
1202  sat_ArrayFree(newOrdered);
1203
1204  if(cm->option->verbose > 3)
1205    sat_PrintScore(cm);
1206
1207}
1208
1209/**Function********************************************************************
1210
1211  Synopsis    [Generate unsat proof in the form of resolution graph]
1212
1213  Description []
1214
1215  SideEffects []
1216
1217  SeeAlso     []
1218
1219******************************************************************************/
1220
1221void
1222sat_GenerateCore_All(satManager_t * cm)
1223{
1224  int i,j,value;
1225  long *lit, ante, node, tmp1;
1226  int  count, inverted;
1227  satLevel_t * d;
1228  satArray_t *clauseArray = sat_ArrayAlloc(1);
1229  int objectFlag;
1230
1231  long conflicting, ante2;
1232  int nMarked,first;
1233  long v,left,right,result,*lp,*tmpIP;
1234  long *space,*tmp;
1235  satArray_t *implied;
1236  RTnode_t  tmprt;
1237  int size = 0, *bLevel;
1238  long *fdaLit=ALLOC(long,1);
1239  boolean endnow;
1240  RTManager_t * rm = cm->rm;
1241
1242  cm->status = 0;
1243  count = 0;
1244  d = SATgetDecision(0);
1245  sat_ImplyArrayWithAnte(cm,d,cm->obj);
1246  sat_ImplyArrayWithAnte(cm,d,cm->auxObj);
1247  sat_ImplyArrayWithAnte(cm,d,cm->assertArray);
1248
1249
1250
1251  if(cm->status==0){
1252  for(i=satNodeSize; i<cm->nodesArraySize; i+=satNodeSize){
1253    node = i;
1254    if((SATflags(node)&IsCNFMask)&&(SATnumLits(node)==1)){
1255      lit = (long*)SATfirstLit(node);
1256      tmp1 = SATgetNode(*lit);
1257      inverted = SATisInverted(tmp1);
1258      tmp1 = SATnormalNode(tmp1);
1259
1260
1261      value = !inverted;
1262      if(SATvalue(tmp1) < 2)    {
1263        if(SATvalue(tmp1) == value)     continue;
1264        else {
1265          cm->status = SAT_UNSAT;
1266          d->conflict = node;
1267          break;
1268        }
1269      }
1270
1271      SATvalue(tmp1) = !inverted;
1272      SATmakeImplied(tmp1, d);
1273      SATante(tmp1) = node;
1274      if((SATflags(tmp1) & InQueueMask) == 0) {
1275        sat_Enqueue(cm->queue, tmp1);
1276        SATflags(tmp1) |= InQueueMask;
1277      }
1278
1279    }
1280  }
1281  }
1282
1283
1284  if(cm->status==0){
1285    sat_ImplicationMain(cm, d);
1286  }
1287
1288  if(d->conflict == 0) {
1289    fprintf(vis_stderr,"There should be a conflict\n");
1290    exit(0);
1291  }
1292
1293  conflicting = d->conflict;
1294  nMarked = 0;
1295
1296  sat_MarkNodeInConflict(
1297          cm, d, &nMarked, &objectFlag, bLevel, clauseArray);
1298  /* Traverse implication graph backward*/
1299  first = 1;
1300  implied = d->implied;
1301  space = implied->space+implied->num-1;
1302
1303
1304
1305  if(cm->option->coreGeneration){
1306    /*if last conflict is CNF*/
1307    if(SATflags(conflicting)&IsCNFMask){
1308      /*is conflict CNF*/
1309      if(SATflags(conflicting)&IsConflictMask){
1310         if(!st_lookup(cm->RTreeTable,(char*)conflicting,&tmprt)){
1311            fprintf(vis_stderr,"RTree node of conflict cnf %ld is not in RTreeTable\n",ante);
1312            exit(0);
1313          }
1314          else{
1315            rm->root = tmprt;
1316#if PR
1317            fprintf(vis_stdout,"Get formula for CONFLICT CLAUSE:%d\n",ante);
1318#endif
1319          }
1320      }
1321      /*CNF but not conflict*/
1322      else{
1323        rm->root = RTCreateNode(rm);
1324
1325        size = SATnumLits(conflicting);
1326        RT_fSize(rm->root) = size;
1327        lp = (long*)SATfirstLit(conflicting);
1328        sat_BuildRT(cm,rm->root, lp, tmpIP,size,0);
1329      }
1330    }
1331    /*if last conflict is AIG*/
1332    else{
1333      rm->root = RTCreateNode(rm);
1334      node = SATnormalNode(conflicting);
1335      left = SATleftChild(node);
1336      right = SATrightChild(node);
1337      result = PureSat_IdentifyConflict(cm,left,right,conflicting);
1338      inverted = SATisInverted(left);
1339      left = SATnormalNode(left);
1340      left = inverted ? SATnot(left) : left;
1341
1342      inverted = SATisInverted(right);
1343      right = SATnormalNode(right);
1344      right = inverted ? SATnot(right) : right;
1345
1346      j = node;
1347
1348      if(result == 1){
1349        tmp = ALLOC(long,3);
1350        tmp[0] = left;
1351        tmp[1] = SATnot(j);
1352        size = 2;
1353      }
1354      else if(result == 2){
1355        tmp = ALLOC(long,3);
1356        tmp[0] = right;
1357        tmp[1] = SATnot(j);
1358        size = 2;
1359      }
1360      else if(result == 3){
1361        tmp = ALLOC(long,4);
1362        tmp[0] = SATnot(left);
1363        tmp[1] = SATnot(right);
1364        tmp[2] = j;
1365        size = 3;
1366      }
1367      else{
1368        fprintf(vis_stderr,"wrong returned result value, exit\n");
1369        exit(0);
1370      }
1371
1372      lp = tmp;
1373      sat_BuildRT(cm,rm->root, lp, tmpIP,size,1);
1374      FREE(tmp);
1375    }
1376  }
1377
1378
1379  endnow = FALSE;
1380  for(i=implied->num-1; i>=0; i--, space--) {
1381    if(endnow)
1382      break;
1383    v = *space;
1384    if(SATflags(v) & VisitedMask) {
1385      SATflags(v) &= ResetVisitedMask;
1386      --nMarked;
1387
1388      if(nMarked == 0 && (!first || i==0))  {
1389        /*value = SATvalue(v);*/
1390        *fdaLit = v^(!value);
1391        sat_ArrayInsert(clauseArray, *fdaLit);
1392        /*break;*/
1393        endnow = TRUE;
1394      }
1395
1396
1397      if(cm->option->coreGeneration){
1398        ante = SATante(v);
1399        if(ante==0){
1400          if(!(st_lookup(cm->anteTable, (char *)SATnormalNode(v),&ante))){
1401            fprintf(vis_stderr,"ante = 0 and is not in anteTable %ld\n",v);
1402            exit(0);
1403          }
1404        }
1405
1406        /*build non-leaf node*/
1407        tmprt = RTCreateNode(rm);
1408        RT_pivot(tmprt) = SATnormalNode(v);
1409        RT_right(tmprt) = rm->root;
1410        rm->root = tmprt;
1411
1412        if((SATflags(ante)&IsConflictMask)&&(SATflags(ante)&IsCNFMask)){
1413          if(!st_lookup(cm->RTreeTable,(char*)ante,&tmprt)){
1414            fprintf(vis_stderr,"RTree node of conflict cnf %ld is not in RTreeTable\n",ante);
1415            exit(0);
1416          }
1417          else{
1418            RT_left(rm->root) = tmprt;
1419#if PR
1420            fprintf(vis_stdout,"Get formula for CONFLICT CLAUSE:%d\n",ante);
1421#endif
1422          }
1423        }
1424        else{ /* if not conflict CNF*/
1425          /*left*/
1426          tmprt = RTCreateNode(rm);
1427          RT_left(rm->root) = tmprt;
1428          /*left is AIG*/
1429          if(!(SATflags(ante) & IsCNFMask)){
1430            /*generate formula for left*/
1431            tmp = ALLOC(long,3);
1432            value = SATvalue(v);
1433            node = SATnormalNode(v);
1434            node = value==1?node:SATnot(node);
1435            tmp[0] = node;
1436
1437            size = 1;
1438            if(ante != SATnormalNode(v)){
1439              value = SATvalue(ante);
1440              node = SATnormalNode(ante);
1441              node = value==1?SATnot(node):node;
1442              tmp[1] = node;
1443              size++;
1444              ante2 = SATante2(v);
1445              if(ante2){
1446                value = SATvalue(ante2);
1447                node = SATnormalNode(ante2);
1448                node = value==1?SATnot(node):node;
1449                tmp[2] = node;
1450                size++;
1451              }
1452            }
1453
1454            lp = tmp;
1455            sat_BuildRT(cm,tmprt,lp,tmpIP,size,1);
1456            FREE(tmp);
1457          }
1458          /* left is CNF*/
1459          else{
1460
1461            lp = (long*)SATfirstLit(ante);
1462            size = SATnumLits(ante);
1463            RT_fSize(tmprt) = size;
1464            sat_BuildRT(cm,tmprt, lp, tmpIP,size,0);
1465          }
1466        } /*else{ // if not conflict CNF*/
1467
1468      }/*if(cm->option->coreGeneration){*/
1469
1470      sat_MarkNodeInImpliedNode(
1471        cm, d, v, &nMarked, &objectFlag, bLevel, clauseArray);
1472    }/*if(SATflags(v) & VisitedMask) {*/
1473    first = 0;
1474  }/*for(i=implied->num-1; i>=*/
1475
1476
1477  if(cm->option->verbose >= 2)
1478    fprintf(vis_stdout,"total # of RTree node:%ld\n",rm->aSize/RTnodeSize);
1479
1480  sat_ArrayFree(clauseArray);
1481  FREE(fdaLit);
1482  if(cm->option->arosat)
1483    AS_Undo(cm,d);
1484  else
1485    sat_Undo(cm,d);
1486  cm->status = SAT_UNSAT;
1487}
1488
1489
1490/**Function********************************************************************
1491
1492  Synopsis    [Merge level for Arosat]
1493
1494  Description []
1495
1496  SideEffects []
1497
1498  SeeAlso     []
1499
1500******************************************************************************/
1501
1502
1503void sat_ASmergeLevel(satManager_t *cm)
1504{
1505  int base;
1506  long v;
1507  satVariable_t *var;
1508  int *assignedArray = cm->assignedArray;
1509  int * numArray = cm->numArray,level=0;
1510
1511  if(cm->option->verbose >= 2)
1512    fprintf(vis_stdout,"MERGE LEVEL\n");
1513  while(cm->LatchLevel>0){
1514  if(cm->option->verbose >= 2)
1515    fprintf(vis_stdout,"Merge level %d and %d\n",cm->LatchLevel, cm->LatchLevel-1);
1516    level++;
1517    cm->LatchLevel--;
1518    if(cm->numArray[cm->LatchLevel]>0)
1519      break;
1520  }
1521  if(cm->option->verbose >= 2)
1522    fprintf(vis_stdout,"After Merge,Latch level:%d\n",cm->LatchLevel);
1523#if DBG
1524  assert(cm->LatchLevel>0);
1525#endif
1526
1527  for(v=satNodeSize;v<cm->initNodesArraySize;v+=satNodeSize){
1528    if(!SATflags(v)&CoiMask)
1529      continue;
1530    var = SATgetVariable(v);
1531    base = var->scores[0]/SCOREUNIT;
1532    if(base==cm->LatchLevel+level){
1533      var->scores[0] = cm->LatchLevel*SCOREUNIT + var->scores[0]%SCOREUNIT;
1534      var->scores[1] = cm->LatchLevel*SCOREUNIT + var->scores[1]%SCOREUNIT;
1535    }
1536  }
1537  assignedArray[cm->LatchLevel]+=assignedArray[cm->LatchLevel+level];
1538  numArray[cm->LatchLevel]+=numArray[cm->LatchLevel+level];
1539
1540}
1541
1542/**Function********************************************************************
1543
1544  Synopsis    [CNF based conflict enforcing]
1545
1546  Description []
1547
1548  SideEffects []
1549
1550  SeeAlso     []
1551
1552******************************************************************************/
1553
1554int sat_CE_CNF(
1555        satManager_t *cm,
1556        satLevel_t *d,
1557        int v,
1558        satArray_t *wl)
1559{
1560  long size, i, *space;
1561  long lit, *plit, dir;
1562  long nv, tv, *oplit, *wlit;
1563  int isInverted, value;
1564  long inverted, clit;
1565  satStatistics_t *stats;
1566  satOption_t *option;
1567  satQueue_t *Q;
1568
1569  size = wl->num;
1570  space = wl->space;
1571  Q = cm->queue;
1572  stats = cm->each;
1573  option = cm->option;
1574
1575  for(i=0; i<size; i++) {
1576    plit = (long*)space[i];
1577
1578    if(plit == 0 || *plit == 0) {
1579
1580      continue;
1581    }
1582
1583    lit = *plit;
1584    dir = SATgetDir(lit);
1585    oplit = plit;
1586
1587    while(1) {
1588      oplit += dir;
1589      if(*oplit <=0) {
1590        if(dir == 1) nv =- (*oplit);
1591        if(dir == SATgetDir(lit)) {
1592          oplit = plit;
1593          dir = -dir;
1594          continue;
1595        }
1596
1597        tv = SATgetNode(*wlit);
1598        isInverted = SATisInverted(tv);
1599        tv = SATnormalNode(tv);
1600        value = SATvalue(tv) ^ isInverted;
1601        if(value == 0) {  /* conflict happens*/
1602
1603          return CONFLICT;
1604        }
1605        else if(value > 1) { /* implication*/
1606          /*implication can only be made on the other wl*/
1607
1608          break;
1609        }
1610
1611        break;
1612      }
1613
1614      clit = *oplit;
1615
1616      tv = SATgetNode(clit);
1617      inverted = SATisInverted(tv);
1618      tv = SATnormalNode(tv);
1619      value = SATvalue(tv) ^ inverted;
1620
1621      if(SATisWL(clit)) { /* found other watched literal*/
1622        wlit = oplit;
1623        /*a little diff from zchaff, if otherwl==1, break*/
1624        if(value == 1)  {
1625          break;
1626        }
1627        /*since it is otherwl, it can't be zero. Here it is unknow*/
1628        continue;
1629      }
1630
1631      if(value == 0)
1632        continue;
1633
1634      /*now it is 1 or unknow*/
1635      break;
1636    }/*while(1)*/
1637  }/*for*/
1638  return NO_CONFLICT;
1639}
1640
1641/**Function********************************************************************
1642
1643  Synopsis    [Conflict enforcing]
1644
1645  Description []
1646
1647  SideEffects []
1648
1649  SeeAlso     []
1650
1651******************************************************************************/
1652int
1653sat_CE(satManager_t *cm,
1654            satLevel_t *d,
1655            long v,
1656            int dfs,
1657            int value)
1658{
1659  long value1,*fan;
1660  long cur, i, size;
1661  long left, right;
1662  satVariable_t *var;
1663  satArray_t *wlArray;
1664
1665  long enforce=0;
1666
1667  v = SATnormalNode(v);
1668
1669  var = SATgetVariable(v);
1670
1671  wlArray = var->wl[value^1];
1672
1673  /*need recovery*/
1674  SATvalue(v) = value;
1675
1676  /* implcation on CNF*/
1677  if(wlArray && wlArray->size) {
1678    if(sat_CE_CNF(cm, d, v, wlArray)==CONFLICT){
1679      enforce = 1;
1680    }
1681  }
1682
1683  /*need recovery*/
1684  SATvalue(v) = value;
1685
1686  if(enforce==0){
1687    /* implication on AIG*/
1688    fan = SATfanout(v);
1689    size = SATnFanout(v);
1690    for(i=0; i<size; i++, fan++) {
1691      cur = *fan;
1692      cur = cur >> 1;
1693      cur = SATnormalNode(cur);
1694      left = SATleftChild(cur);
1695      right = SATrightChild(cur);
1696      value1 = SATgetValue(left, right, cur);
1697      if(value1==1||value1==5||value1==9||value1==13||value1==17
1698         ||value1==20||value1==33||value1==49){
1699        /*fprintf(vis_stdout,"AIG Output enforce\n");*/
1700        enforce=1;
1701        break;
1702      }
1703    }
1704  }
1705
1706  if(enforce==0){
1707    left = SATleftChild(v);
1708    right = SATrightChild(v);
1709    if(left!=2&&right!=2){
1710      value1 = SATgetValue(left, right, v);
1711      if(value1==1||value1==5||value1==9||value1==13||value1==17
1712         ||value1==20||value1==33||value1==49){
1713        /*fprintf(vis_stdout,"AIG Children enforce\n");*/
1714        enforce=1;
1715      }
1716    }
1717  }
1718
1719
1720  SATvalue(v)=2;
1721
1722  return enforce;
1723
1724}
1725
1726/**Function********************************************************************
1727
1728  Synopsis    [Decision procedure for Arosat]
1729
1730  Description []
1731
1732  SideEffects []
1733
1734  SeeAlso     []
1735
1736******************************************************************************/
1737
1738
1739int sat_ASDec(satManager_t *cm,
1740              satLevel_t *d,
1741              long v)
1742{
1743  int dfs;
1744  int *numArray,*assignedArray;
1745  satVariable_t *var=SATgetVariable(v);
1746
1747  assignedArray = cm->assignedArray;
1748  numArray = cm->numArray;
1749
1750  v = SATnormalNode(v);
1751  dfs = var->scores[0]/SCOREUNIT;
1752
1753#if DBG
1754
1755  assert(dfs==cm->LatchLevel);
1756  assert(!(SATflags(SATnormalNode(v)) & InQueueMask));
1757  assert(SATvalue(SATnormalNode(v))==2);
1758#endif
1759  if(!(SATflags(SATnormalNode(v))&AssignedMask)){
1760    SATflags(SATnormalNode(v))|=AssignedMask;
1761    assignedArray[dfs]++;
1762    /* if(dfs==cm->OriLevel)
1763    //  fprintf(vis_stdout,"Assign Level %d: %d dfs=%d assArray[%d]=%d\n",
1764    //     d->level,v,dfs,dfs,cm->assignedArray[dfs]);*/
1765
1766    if(cm->assignedArray[dfs]==cm->numArray[dfs])
1767      sat_ASmergeLevel(cm);
1768    /*fprintf(vis_stdout,"Decisionlevel:%d: %d dfs=%d,assArray[%d]=%d, numArray[%d]=%d\n",
1769      //      d->level,v,dfs,dfs,assignedArray[dfs],dfs,numArray[dfs]);*/
1770  }
1771  return 0;
1772}
1773
1774/**Function********************************************************************
1775
1776  Synopsis    [Implication procedure for Arosat]
1777
1778  Description []
1779
1780  SideEffects []
1781
1782  SeeAlso     []
1783
1784******************************************************************************/
1785int
1786sat_ASImp(satManager_t *cm,
1787          satLevel_t *d,
1788          long v,
1789          int value)
1790{
1791  int dfs;
1792  long tmpv;
1793  int *numArray,*assignedArray;
1794  satVariable_t *var=SATgetVariable(v);
1795
1796  assignedArray = cm->assignedArray;
1797  numArray = cm->numArray;
1798
1799  v = SATnormalNode(v);
1800
1801#if DBG
1802  assert(SATvalue(v)==2);
1803#endif
1804  dfs = var->scores[0]/SCOREUNIT;
1805
1806
1807  if(dfs==cm->LatchLevel){
1808    if(!(SATflags(SATnormalNode(v))&AssignedMask)){
1809
1810      SATflags(SATnormalNode(v))|=AssignedMask;
1811      assignedArray[dfs]++;
1812
1813#if DBG
1814      assert(assignedArray[dfs]<=numArray[dfs]);
1815#endif
1816      if(cm->assignedArray[dfs]==cm->numArray[dfs])
1817        sat_ASmergeLevel(cm);
1818
1819    }
1820
1821    return 0;
1822  }
1823  else{
1824    /*if conflict enforcing*/
1825    if(sat_CE(cm,d,v,dfs,value)){
1826
1827      if(!(SATflags(SATnormalNode(v))&AssignedMask)){
1828        SATflags(SATnormalNode(v))|=AssignedMask;
1829        assignedArray[dfs]++;
1830
1831#if DBG
1832        assert(assignedArray[dfs]<=numArray[dfs]);
1833#endif
1834
1835      }
1836
1837      return 0;
1838    }
1839    /*else implication is prohibited*/
1840    else{
1841
1842#if DBG
1843      assert(value==0||value==1);
1844#endif
1845      if(value==0)
1846        tmpv = -1;
1847      else
1848        tmpv = 1;
1849      SATgetVariable(v)->RecVal = tmpv;
1850
1851      return 1;
1852    }
1853  }
1854  return 0;
1855}
Note: See TracBrowser for help on using the repository browser.