CaDiCal2019学习笔记(4)
phases.hpp
1 typedef signed char Phase; 2 3 struct Phases { 4 5 Phase * saved; // The actual saved phase. 6 Phase * target; // The current target phase. 7 Phase * best; // The current largest trail phase. 8 Phase * prev; // Previous during local search. 9 Phase * min; // The current minimum unsatisfied phase. 10 11 Phases () : saved (0), target (0), best (0), prev (0), min (0) { } 12 }; |
声明了Phases类型,似乎变元用作节点时,拥有这个属性可以链接很多求解进程中的过程量(前世今生^_^) |
phases.cpp
1 #include "internal.hpp" 2 3 namespace CaDiCaL { 4 5 void Internal::copy_phases (Phase * & dst) { 6 assert (sizeof (Phase) == 1); 7 memcpy (dst, vals, max_var + 1); 8 } 9 10 void Internal::clear_phases (Phase * & dst) { 11 assert (sizeof (Phase) == 1); 12 memset (dst, 0, max_var + 1); 13 } 14 15 } |
对internal.hpp中声明的类型Internal相应成员函数的实现,操作了该类的数据成员vals. |
让我们看看internal.h中的相关代码:
155 signed char * vals; // assignment [-max_var,max_var] 156 signed char * marks; // signed marks [1,max_var] 157 Phases phases; // saved, target and best phases |
231 // Enlarge tables. 232 // 233 void enlarge_vals (size_t new_vsize); 234 void enlarge (int new_max_var); |
476 // Functions to set and reset certain 'phases'. 477 // 478 void clear_phases (Phase * &); // reset to zero 479 void copy_phases (Phase * &); // copy 'vals' to 'argument' //phases.ccp line 5. |
891 // Get the value of an internal literal: -1=false, 0=unassigned, 1=true. 892 // We use a redundant table for both negative and positive literals. This 893 // allows a branch-less check for the value of literal and is considered 894 // substantially faster than negating the result if the argument is 895 // negative. We also avoid taking the absolute value. 896 // 897 int val (int lit) const { 898 assert (-max_var <= lit), assert (lit), assert (lit <= max_var); 899 return vals[lit]; 900 }
|
902 // As 'val' but restricted to the root-level value of a literal. 903 // It is not that time critical and also needs to check the decision level 904 // of the variable anyhow. 905 // 906 int fixed (int lit) { 907 assert (-max_var <= lit), assert (lit), assert (lit <= max_var); 908 int idx = vidx (lit), res = vals[idx]; 909 if (res && vtab[idx].level) res = 0; 910 if (lit < 0) res = -res; 911 return res; 912 } |
对应在internal.cpp中的相关代码:
1 Internal::~Internal () { 2 for (const auto & c : clauses) 3 delete_clause (c); 4 if (proof) delete proof; 5 if (tracer) delete tracer; 6 if (checker) delete checker; 7 if (vtab) DELETE_ONLY (vtab, Var, vsize); 8 if (ltab) DELETE_ONLY (ltab, Link, vsize); 9 if (ftab) DELETE_ONLY (ftab, Flags, vsize); 10 if (btab) DELETE_ONLY (btab, long, vsize); 11 if (stab) DELETE_ONLY (stab, double, vsize); 12 if (ptab) DELETE_ONLY (ptab, int, 2*vsize); 13 if (big) RELEASE_DELETE (big, Bins, 2*vsize); 14 if (vals) { vals -= vsize; DELETE_ONLY (vals, signed_char, 2*vsize); } 15 if (marks) DELETE_ONLY (marks, signed_char, vsize); 16 if (phases.saved) DELETE_ONLY (phases.saved, Phase, vsize); 17 if (phases.target) DELETE_ONLY (phases.target, Phase, vsize); 18 if (phases.best) DELETE_ONLY (phases.best, Phase, vsize); 19 if (phases.prev) DELETE_ONLY (phases.prev, Phase, vsize); 20 if (phases.min) DELETE_ONLY (phases.min, Phase, vsize); 21 if (i2e) DELETE_ONLY (i2e, int, vsize); 22 if (frozentab) DELETE_ONLY (frozentab, unsigned, vsize); 23 if (otab) reset_occs (); 24 if (ntab) reset_noccs (); 25 if (wtab) reset_watches (); 26 } |
1 void Internal::enlarge_vals (size_t new_vsize) { 2 signed_char * new_vals; 3 NEW_ZERO (new_vals, signed_char, 2*new_vsize); 4 new_vals += new_vsize; 5 if (vals) memcpy (new_vals - max_var, vals - max_var, 2*max_var + 1); 6 vals -= vsize; 7 DELETE_ONLY (vals, signed_char, 2*vsize); 8 vals = new_vals; 9 } 10 11 void Internal::enlarge (int new_max_var) { 12 assert (!level); 13 size_t new_vsize = vsize ? 2*vsize : 1 + (size_t) new_max_var; 14 while (new_vsize <= (size_t) new_max_var) new_vsize *= 2; 15 LOG ("enlarge internal size from %ld to new size %ld", vsize, new_vsize); 16 // Ordered in the size of allocated memory (larger block first). 17 assert (!vsize || !otab); 18 if (!vsize || wtab) 19 ENLARGE_ZERO (wtab, Watches, 2*vsize, 2*new_vsize); 20 ENLARGE_ONLY (vtab, Var, vsize, new_vsize); 21 ENLARGE_ONLY (ltab, Link, vsize, new_vsize); 22 ENLARGE_ZERO (btab, long, vsize, new_vsize); 23 ENLARGE_ZERO (stab, double, vsize, new_vsize); 24 ENLARGE_ONLY (ptab, int, 2*vsize, 2*new_vsize); 25 ENLARGE_ONLY (i2e, int, vsize, new_vsize); 26 enlarge_vals (new_vsize); 27 ENLARGE_ZERO (frozentab, unsigned, vsize, new_vsize); 28 ENLARGE_ONLY (phases.saved, Phase, vsize, new_vsize); 29 ENLARGE_ZERO (phases.target, Phase, vsize, new_vsize); 30 ENLARGE_ZERO (phases.best, Phase, vsize, new_vsize); 31 ENLARGE_ZERO (phases.prev, Phase, vsize, new_vsize); 32 ENLARGE_ZERO (phases.min, Phase, vsize, new_vsize); 33 ENLARGE_ZERO (marks, signed_char, vsize, new_vsize); 34 ENLARGE_ONLY (ftab, Flags, vsize, new_vsize); 35 vsize = new_vsize; 36 } 37 38 void Internal::init (int new_max_var) { 39 if (new_max_var <= max_var) return; 40 if (level) backtrack (); 41 LOG ("initializing %d internal variables from %d to %d", 42 new_max_var - max_var, max_var + 1, new_max_var); 43 if ((size_t) new_max_var >= vsize) enlarge (new_max_var); 44 signed_char val = opts.phase ? 1 : -1; 45 for (int i = max_var + 1; i <= new_max_var; i++) 46 phases.saved[i] = val; 47 #ifndef NDEBUG 48 for (int i = -new_max_var; i < -max_var; i++) assert (!vals[i]); 49 for (int i = max_var + 1; i <= new_max_var; i++) assert (!vals[i]); 50 for (int i = max_var + 1; i <= new_max_var; i++) assert (!frozentab[i]); 51 for (int i = max_var + 1; i <= new_max_var; i++) assert (!marks[i]); 52 for (int i = max_var + 1; i <= new_max_var; i++) assert (!btab[i]); 53 #endif 54 for (int i = 2*(max_var + 1); i <= 2*new_max_var+1; i++) ptab[i] = -1; 55 for (int i = max_var + 1; i <= new_max_var; i++) ftab[i].init (); 56 assert (!btab[0]); 57 int old_max_var = max_var; 58 max_var = new_max_var; 59 init_queue (old_max_var, new_max_var); 60 init_scores (old_max_var, new_max_var); 61 int initialized = new_max_var - old_max_var; 62 stats.vars += initialized; 63 stats.unused += initialized; 64 stats.inactive += initialized; 65 LOG ("finished initializing %d internal variables", initialized); 66 } 67 68 void Internal::add_original_lit (int lit) { 69 assert (abs (lit) <= max_var); 70 if (lit) { 71 original.push_back (lit); 72 } else { 73 if (proof) proof->add_original_clause (original); 74 add_new_original_clause (); 75 original.clear (); 76 } 77 } |
顺便了解一下在CaDiCal中CDCL实现过程
1 // This is the main CDCL loop with interleaved inprocessing. 2 3 int Internal::cdcl_loop_with_inprocessing () { 4 5 int res = 0; 6 7 START (search); 8 9 if (stable) { START (stable); report ('['); } 10 else { START (unstable); report ('{'); } 11 12 while (!res) { 13 if (unsat) res = 20; 14 else if (!propagate ()) analyze (); // propagate and analyze 15 else if (iterating) iterate (); // report learned unit 16 else if (satisfied ()) res = 10; // found model 17 else if (terminating ()) break; // limit hit or sync abort 18 else if (restarting ()) restart (); // restart by backtracking 19 else if (rephasing ()) rephase (); // reset variable phases 20 else if (reducing ()) reduce (); // collect useless clauses 21 else if (probing ()) probe (); // failed literal probing 22 else if (subsuming ()) subsume (); // subsumption algorithm 23 else if (eliminating ()) elim (); // variable elimination 24 else if (compacting ()) compact (); // collect variables 25 else res = decide (); // next decision 26 } 27 28 if (stable) { STOP (stable); report (']'); } 29 else { STOP (unstable); report ('}'); } 30 31 STOP (search); 32 33 return res; 34 } |
使用while循环将CDCL主要求解过程(传播、冲突分析、重启、相位保留/选择、化简、随机局部探索、学习子句集的缩减管理等)串起来形成算法。 |