需要查看以下文件

restart.h、restart.c、mode.h、mode.c、search.c

backtrack.h backtrack.c

limit.h  limit.c

trail.h  trail.c

frames.h  frames.c

decide.h  decide.c


 

1.重启涉及的物理量

重启涉及的物理量
solver->heuristic
solver->mab solver
->statistics.restarts
solver->limits.restart.conflicts limits
*limits = &solver->limits; limits->restart.conflicts
还涉及相关reuse_trail
const unsigned next_idx = kissat_next_decision_variable (solver); const links *links = solver->links; const unsigned next_idx_stamp = links[next_idx].stamp; LOG ("next decision variable stamp %u", next_idx_stamp);

 

2.判断重启的条件

 
 1 bool
 2 kissat_restarting (kissat * solver)
 3 {
 4   assert (solver->unassigned);
 5   if (!GET_OPTION (restart))
 6     return false;
 7   if (!solver->level)
 8     return false;
 9   if (CONFLICTS < solver->limits.restart.conflicts)
10     return false;
11   kissat_switch_search_mode (solver);
12   if (solver->stable)
13     return kissat_reluctant_triggered (&solver->reluctant);//稳定状态时触发重启的条件
14   const double fast = AVERAGE (fast_glue);
15   const double slow = AVERAGE (slow_glue);
16   const double margin = (100.0 + GET_OPTION (restartmargin)) / 100.0;
17   const double limit = margin * slow;
18   LOG ("restart glue limit %g = %.02f * %g (slow glue) %c %g (fast glue)",
19        limit, margin, slow,
20        (limit > fast ? '>' : limit == fast ? '=' : '<'), fast);
21   return limit <= fast;  //focused状态时触发重启的条件
22 }

 

   

3.实施重启的函数

 
 1 void
 2 kissat_restart (kissat * solver)
 3 {
 4   START (restart);  
 5   INC (restarts);
 6   
 7   unsigned old_heuristic = solver->heuristic;
 8   if (solver->stable && solver->mab) 
 9      restart_mab(solver);
10   unsigned new_heuristic = solver->heuristic;
11 
12   unsigned level = old_heuristic==new_heuristic?reuse_trail (solver):0;
13 
14   kissat_extremely_verbose (solver,
15                 "restarting after %" PRIu64 " conflicts"
16                 " (scheduled at %" PRIu64 ")",
17                 CONFLICTS, solver->limits.restart.conflicts);
18   LOG ("restarting to level %u", level);
19 
20   if (solver->stable && solver->mab) solver->heuristic = old_heuristic;
21   kissat_backtrack (solver, level);
22   if (solver->stable && solver->mab) solver->heuristic = new_heuristic;
23 
24   if (!solver->stable)
25     kissat_new_focused_restart_limit (solver);
26 
27   if (solver->stable && solver->mab && old_heuristic!=new_heuristic) 
kissat_update_scores(solver);
28 29 REPORT (1, 'R'); 30 STOP (restart); 31 }

其中,restart_mab(solver)实施重启;其余几个函数是辅助功能。

   

 

4.涉及重启策略转换、回溯、重启后reusetrail、相位保持以及变元选择策略等功能代码需要重点分析.

 

(1) 

solver->stable 对变量计算分数,后续用于确定决策变元选择;

非solver->stable,时采用VMTF机制最近冲突时传播到的变元移动到队列前部供选择;

//见decide.c文件

 1 unsigned
 2 kissat_next_decision_variable (kissat * solver)
 3 {
 4   unsigned res;
 5   if (solver->stable)
 6     res = largest_score_unassigned_variable (solver,
solver->heuristic==0?&solver->scores:&solver->scores_chb); 7 else 8 res = last_enqueued_unassigned_variable (solver); 9 LOG ("next decision variable %u", res); 10 return res; 11 }

 

变元计分涉及两个堆heap 

 1 static unsigned
 2 largest_score_unassigned_variable (kissat * solver, heap * heap)
 3 {
 4   unsigned res = kissat_max_heap (heap);
 5   const value *values = solver->values;
 6   while (values[LIT (res)])
 7     {
 8       kissat_pop_heap (solver, heap, res);
 9       res = kissat_max_heap (heap);
10     }
11 
12   // MAB
13   if(solver->mab) {
14     solver->mab_decisions++;
15     if(!solver->mab_chosen[res]){
16         solver->mab_chosen_tot++;
17         solver->mab_chosen[res] = 1;
18     }
19   }
20 
21 #if defined(LOGGING) || defined(CHECK_HEAP)
22   const double score = kissat_get_heap_score (heap, res);
23 #endif
24   LOG ("largest score unassigned variable %u score %g", res, score);
25 #ifdef CHECK_HEAP
26   for (all_variables (idx))
27     {
28       if (VALUE (LIT (idx)))
29     continue;
30       const double idx_score = kissat_get_heap_score (heap, idx);
31       assert (score >= idx_score);
32     }
33 #endif
34   return res;
35 }

 

VMTF涉及linked链表

static unsigned
last_enqueued_unassigned_variable (kissat * solver)
{
  assert (solver->unassigned);
  const links *links = solver->links;
  const value *values = solver->values;
  unsigned res = solver->queue.search.idx;
  if (values[LIT (res)])
    {
      do
    {
      res = links[res].prev;
      assert (!DISCONNECTED (res));
    }
      while (values[LIT (res)]);
      kissat_update_queue (solver, links, res);
    }
#ifdef LOGGING
  const unsigned stamp = links[res].stamp;
  LOG ("last enqueued unassigned variable %u stamp %u", res, stamp);
#endif
#ifdef CHECK_QUEUE
  for (unsigned i = links[res].next; !DISCONNECTED (i); i = links[i].next)
    assert (VALUE (LIT (i)));
#endif
  return res;
}

 

   
 

(2) 相位选择策略

 1 static inline value
 2 decide_phase (kissat * solver, unsigned idx)
 3 {
 4   bool force = GET_OPTION (forcephase);
 5 
 6   bool target;
 7   if (force)
 8     target = false;
 9   else if (!GET_OPTION (target))
10     target = false;
11   else if (solver->stable)
12     target = true;
13   else
14     target = (GET_OPTION (target) > 1);
15 
16   const bool saved = !force && GET_OPTION (phasesaving);
17 
18   const phase *phase = PHASE (idx);
19   value res = 0;
20 
21   if (target && (res = phase->target))
22     {
23       LOG ("variable %u uses target decision phase %d", idx, (int) res);
24       INC (target_decisions);
25     }
26 
27   if (saved && !res && (res = phase->saved))
28     {
29       LOG ("variable %u uses saved decision phase %d", idx, (int) res);
30       INC (saved_decisions);
31     }
32 
33   if (!res)
34     {
35       res = INITIAL_PHASE;
36       LOG ("variable %u uses initial decision phase %d", idx, (int) res);
37       INC (initial_decisions);
38     }
39   assert (res);
40 
41   return res;
42 }

 

   
 

 (3) 关于trail更新

//trail.c

 1 void
 2 kissat_flush_trail (kissat * solver)
 3 {
 4   assert (!solver->level);
 5   assert (solver->unflushed);
 6   assert (!solver->inconsistent);
 7   assert (kissat_propagated (solver));
 8   assert (SIZE_STACK (solver->trail) == solver->unflushed);
 9   LOG ("flushed %zu units from trail", SIZE_STACK (solver->trail));
10   CLEAR_STACK (solver->trail);
11   solver->unflushed = 0;
12   solver->propagated = 0;
13 }

 

 1 void
 2 kissat_restart_and_flush_trail (kissat * solver)
 3 {
 4   if (solver->level)
 5     {
 6       LOG ("forced restart");
 7       kissat_backtrack (solver, 0);
 8     }
 9 #ifndef NDEBUG
10   clause *conflict =
11 #endif
12     kissat_search_propagate (solver);   
13   assert (!conflict);
14   if (solver->unflushed)
15     kissat_flush_trail (solver);   
16 }

 

对指定trail中参考点大于start的文字所对应reason子句进行标定

//trail.c

 1 void
 2 kissat_mark_reason_clauses (kissat * solver, reference start)
 3 {
 4   LOG ("starting marking reason clauses at clause[%zu]", start);
 5   assert (!solver->unflushed);
 6 #ifdef LOGGING
 7   unsigned reasons = 0;
 8 #endif 
 9   word *arena = BEGIN_STACK (solver->arena); 
10   for (all_stack (unsigned, lit, solver->trail))
11     { 
12       assigned *a = ASSIGNED (lit);
13       assert (a->level > 0);
14       if (a->binary)
15     continue;
16       const reference ref = a->reason;
17       assert (ref != UNIT);
18       if (ref == DECISION)
19     continue;
20       if (ref < start)
21     continue;
22       clause *c = (clause *) (arena + ref);
23       assert (kissat_clause_in_arena (solver, c)); 
24       c->reason = true;
25 #ifdef LOGGING
26       reasons++;
27 #endif
28     }
29   LOG ("marked %u reason clauses", reasons);
30 }

去标定,下面这个与上面的代码总体时一致的,不同之处在line24-25

 1 void
 2 kissat_unmark_reason_clauses (kissat * solver, reference start)
 3 {
 4   LOG ("starting unmarking reason clauses at clause[%zu]", start);
 5   assert (!solver->unflushed);
 6 #ifdef LOGGING
 7   unsigned reasons = 0;
 8 #endif
 9   word *arena = BEGIN_STACK (solver->arena);
10   for (all_stack (unsigned, lit, solver->trail))
11     {
12       assigned *a = ASSIGNED (lit);
13       assert (a->level > 0);
14       if (a->binary)
15     continue;
16       const reference ref = a->reason;
17       assert (ref != UNIT);
18       if (ref == DECISION)
19     continue;
20       if (ref < start)
21     continue;
22       clause *c = (clause *) (arena + ref);
23       assert (kissat_clause_in_arena (solver, c));
24       assert (c->reason);
25       c->reason = false;
26 #ifdef LOGGING
27       reasons++;
28 #endif
29     }
30   LOG ("unmarked %u reason clauses", reasons);
31 }

 

   
 

 (4)回溯backtrack

 1 void
 2 kissat_backtrack (kissat * solver, unsigned new_level)
 3 {
 4   assert (solver->level >= new_level);
 5   if (solver->level == new_level)
 6     return;
 7 
 8   update_phases (solver);
 9   LOG ("backtracking to decision level %u", new_level);
10 
11   frame *new_frame = &FRAME (new_level + 1);
12   const unsigned new_size = new_frame->trail;
13   SET_END_OF_STACK (solver->frames, new_frame);
14 
15   value *values = solver->values;
16   unsigned *trail = BEGIN_STACK (solver->trail);
17   assigned *assigned = solver->assigned;
18 
19   const unsigned old_size = SIZE_STACK (solver->trail);
20   unsigned unassigned = 0, reassigned = 0;
21 
22   unsigned j = new_size;
23   if (solver->stable)
24     {
25       heap *scores = solver->heuristic==0?&solver->scores:&solver->scores_chb;
26       for (unsigned i = j; i != old_size; i++)
27     {
28       const unsigned lit = trail[i];
29       const unsigned idx = IDX (lit);
30       assert (idx < VARS);
31       const unsigned level = assigned[idx].level;
32       if (level <= new_level)
33         {
34           trail[j++] = lit;
35           LOG ("reassign %s", LOGLIT (lit));
36           reassigned++;
37         }
38       else
39         {
40           unassign (solver, values, lit);
41           add_unassigned_variable_back_to_heap (solver, scores, lit);
42           unassigned++;
43         }
44     }
45     }
46   else
47     {
48       links *links = solver->links;
49       for (unsigned i = j; i != old_size; i++)
50     {
51       const unsigned lit = trail[i];
52       const unsigned idx = IDX (lit);
53       assert (idx < VARS);
54       const unsigned level = assigned[idx].level;
55       if (level <= new_level)
56         {
57           trail[j++] = lit;
58           LOG ("reassign %s", LOGLIT (lit));
59           reassigned++;
60         }
61       else
62         {
63           unassign (solver, values, lit);
64           add_unassigned_variable_back_to_queue (solver, links, lit);
65           unassigned++;
66         }
67     }
68     }
69   RESIZE_STACK (solver->trail, j);
70 
71   solver->level = new_level;
72   LOG ("unassigned %u literals", unassigned);
73   LOG ("reassigned %u literals", reassigned);
74   (void) unassigned, (void) reassigned;
75 
76   assert (new_size <= SIZE_STACK (solver->trail));
77   LOG ("propagation will resume at trail position %u", new_size);
78   solver->propagated = new_size;
79 
80   assert (!solver->extended);
81 }

 

 出现backtrack的情况:

 1 ----------  D:\studySAT\studySAT2023_04_28\Kissat_MAB-HyWalk_hornFrist\src\analyze.c
 2 [69]       kissat_backtrack (solver, conflict_level);
 3 [116]   kissat_backtrack (solver, solver->level - 1);
 4 
 5 ----------  D:\studySAT\studySAT2023_04_28\Kissat_MAB-HyWalk_hornFrist\src\backtrack.c
 6 [77] kissat_backtrack (kissat * solver, unsigned new_level)
 7 [159] kissat_backtrack_propagate_and_flush_trail (kissat * solver)
 8 [165]       kissat_backtrack (solver, 0);
 9 
10 ----------  D:\studySAT\studySAT2023_04_28\Kissat_MAB-HyWalk_hornFrist\src\backtrack.h
11 [6] void kissat_backtrack (struct kissat *, unsigned level);
12 [7] void kissat_backtrack_propagate_and_flush_trail (struct kissat *);
13 
14 ----------  D:\studySAT\studySAT2023_04_28\Kissat_MAB-HyWalk_hornFrist\src\eliminate.c
15 [582]   kissat_backtrack_propagate_and_flush_trail (solver);
16 
17 ----------  D:\studySAT\studySAT2023_04_28\Kissat_MAB-HyWalk_hornFrist\src\failed.c
18 [291]       kissat_backtrack (solver, 0);
19 
20 ----------  D:\studySAT\studySAT2023_04_28\Kissat_MAB-HyWalk_hornFrist\src\internal.c
21 [438]           kissat_backtrack (solver, k - 1);
22 
23 ----------  D:\studySAT\studySAT2023_04_28\Kissat_MAB-HyWalk_hornFrist\src\learn.c
24 [52]   kissat_backtrack (solver, new_level);
25 [67]   kissat_backtrack (solver, new_level);
26 [112]   kissat_backtrack (solver, new_level);
27 
28 ----------  D:\studySAT\studySAT2023_04_28\Kissat_MAB-HyWalk_hornFrist\src\probe.c
29 [27]   kissat_backtrack_propagate_and_flush_trail (solver);
30 
31 ----------  D:\studySAT\studySAT2023_04_28\Kissat_MAB-HyWalk_hornFrist\src\rephase.c
32 [203]   kissat_backtrack_propagate_and_flush_trail (solver);
33 
34 ----------  D:\studySAT\studySAT2023_04_28\Kissat_MAB-HyWalk_hornFrist\src\restart.c
35 [154]   kissat_backtrack (solver, level);
36 
37 ----------  D:\studySAT\studySAT2023_04_28\Kissat_MAB-HyWalk_hornFrist\src\trail.c
38 [57]       kissat_backtrack (solver, 0);
39 
40 ----------  D:\studySAT\studySAT2023_04_28\Kissat_MAB-HyWalk_hornFrist\src\vivify.c
41 [496]     kissat_backtrack (solver, 0);
42 [702]       kissat_backtrack (solver, level - 1);
43 [760]       kissat_backtrack (solver, level - 1);
44 [961]     kissat_backtrack (solver, 0);

 

   
posted on 2023-05-26 09:50  海阔凭鱼跃越  阅读(43)  评论(0编辑  收藏  举报