需要查看以下文件
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) 其中,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,
变元计分涉及两个堆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);
|
|