细节决定成败

谈以下对求解器类型以下数据成员与成员函数的使用修正。

(1)analyze和collectFirstUIP函数使用

(2)vardata的使用


 1.关于pathCs和seen的使用

analyze和collectFirstUIP函数都非常巧妙地使用pathCs和seen进行遍历冲突生成的传播路径

注意:相关修改和借用,需要确保reason中的c0为BCP蕴含文字。

由于传播函数在处理观察时未对watches_bin的观察元对应子句做相应的文字调整处理,所以最为直接的方法是在传播阶段确保二元子句作为reason时蕴含文字处在0位置,对下面两个函数增加部分代码:

 
 1 void Solver::uncheckedEnqueue(Lit p, CRef from)
 2 {
 3     assert(value(p) == l_Undef);
 4     //====================================================
 5     if (from != CRef_Undef) {
 6         Clause& c = ca[from];
 7         if (p != lit_Undef && c.size() == 2 && c[0] != p) {
 8             assert(value(c[0]) == l_False);
 9             assert(c[1] == p);
10             Lit tmp = c[0];
11             c[0] = c[1], c[1] = tmp;
12         }
13     }
14     //====================================================
15 
16     Var x = var(p);
17     if (!VSIDS){
18         picked[x] = conflicts;
19         conflicted[x] = 0;
20         almost_conflicted[x] = 0;
21 #ifdef ANTI_EXPLORATION
22         uint32_t age = conflicts - canceled[var(p)];
23         if (age > 0){
24             double decay = pow(0.95, age);
25             activity_CHB[var(p)] *= decay;
26             if (order_heap_CHB.inHeap(var(p)))
27                 order_heap_CHB.increase(var(p));
28         }
29 #endif
30     }
31 
32     assigns[x] = lbool(!sign(p));
33     vardata[x] = mkVarData(from, decisionLevel());
34     trail.push_(p);  
35 }

 

 
 1 void Solver::simpleUncheckEnqueue(Lit p, CRef from){
 2     assert(value(p) == l_Undef);
 3     //===================================================
 4     if (from != CRef_Undef) {
 5         Clause& c = ca[from];
 6         if (p != lit_Undef && c.size() == 2 && c[0] != p) {
 7             assert(value(c[0]) == l_False);
 8             assert(c[1] == p);
 9             Lit tmp = c[0];
10             c[0] = c[1], c[1] = tmp;
11         }
12     }
13     //===================================================
14     assigns[var(p)] = lbool(!sign(p)); // this makes a lbool object whose value is sign(p)
15     vardata[var(p)].reason = from;
16     trail.push_(p);
17 }

 

   

 

2. 关于vardata的使用

       回溯函数中,文字在回退时其vardata并没有改变,部分特殊文字如果保留在最后回退层中,如果仅trail.push_(add_tmp[nLitId]),使用vardata[x].level获取层数属性就是错误的,应该使用uncheckequeue函数,确保文字的层属性与当前所处的层是一致的。

       所以再回退函数中,做如下修改是必要的。(除非不使用获取层数属性)

   
 
 1 void Solver::cancelUntil(int bLevel) {
 2     add_tmp.clear();
 3     if (decisionLevel() > bLevel){
 4         for (int c = trail.size()-1; c >= trail_lim[bLevel]; c--){
 5             Var      x  = var(trail[c]);
 6         int curLevel = level(x);
 7             if ( curLevel<= bLevel)
 8         {
 9         add_tmp.push(trail[c]);
10         }
11         else
12         {
13                 if (!VSIDS){
14                       。。。
15                 }
16                 assigns [x] = l_Undef;
17                 if (phase_saving > 1 || (phase_saving == 1) && c > trail_lim.last())
18                     polarity[x] = sign(trail[c]);
19                 insertVarOrder(x);
20             }
21         }
22         qhead = trail_lim[bLevel];
23 
24         trail.shrink(trail.size() - trail_lim[bLevel]);
25   
26         for (int nLitId = add_tmp.size() - 1; nLitId >= 0; --nLitId)
27         {
28             //trail.push_(add_tmp[nLitId]);
29             //int varindex = (trail.size() - 1);
30         31             //上面两行代码应该被下面语句段代替
32             //---------------------------------
33             Var  x  = var(add_tmp[nLitId]);
34             CRef from = vardata[x].reason;
35             uncheckedEnqueue(add_tmp[nLitId], from);            
36             //---------------------------------
37         }        
38         add_tmp.clear();
39     } 
40 }

 

   
   
   

 

posted on 2023-09-18 23:19  海阔凭鱼跃越  阅读(29)  评论(0编辑  收藏  举报